unity的C#学习——方法的定义、调用、递归与参数传递

2023-11-02


C# 方法

一个方法是把一些相关的语句组织在一起,用来执行一个任务的语句块。通常我们会把这样的语句块称为函数,然后将定义在类当中的函数称为类方法。

由于C#是面向对象的语言,要求所有代码语句都写在类当中,所以严格上来说C#只讲方法不讲函数,每一个 C# 程序至少有一个带有 Main 方法的类。


1、方法的定义与调用

要使用一个方法,需要先定义方法,再调用方法。当定义一个方法时,从根本上说是在声明它的结构的元素。在 C# 中,定义方法的语法如下:

<Access Specifier> <Return Type> <Method Name>(Parameter List)
{
   Method Body
}

其中:

  • Access Specifier:访问修饰符,这个决定了变量或方法对于另一个类的可见性。
  • Return type:返回类型,一个方法可以返回一个值。返回类型是方法返回的值的数据类型。如果方法不返回任何值,则返回类型为 void。
  • Method name:方法名称,是一个唯一的标识符,且是大小写敏感的。它不能与类中声明的其他标识符相同。
  • Parameter list:参数列表,使用圆括号括起来,该参数是用来传递和接收方法的数据。参数列表是指方法的参数类型、顺序和数量。参数是可选的,也就是说,一个方法可能不包含参数。
  • Method body:方法主体,包含了完成任务所需的指令集。

下面的代码片段显示一个函数 FindMax,它接受两个整数值,并返回两个中的较大值。它有 public 访问修饰符,所以它可以使用类的实例从类的外部进行访问。

class NumberManipulator
{
   public int FindMax(int num1, int num2)
   {
      /* 局部变量声明 */
      int result;

      if (num1 > num2)
         result = num1;
      else
         result = num2;

      return result;
   }
   ...
}

定义好方法后,就可以使用方法名调用方法。下面的实例演示了这点:

using System;

namespace CalculatorApplication
{
   class NumberManipulator
   {
      public int FindMax(int num1, int num2)
      {
         /* 局部变量声明 */
         int result;

         if (num1 > num2)
            result = num1;
         else
            result = num2;

         return result;
      }
      static void Main(string[] args)
      {
         /* 局部变量定义 */
         int a = 100;
         int b = 200;
         int ret;
         NumberManipulator n = new NumberManipulator();

         //调用 FindMax 方法
         ret = n.FindMax(a, b);
         Console.WriteLine("最大值是: {0}", ret );
         Console.ReadLine();
      }
   }
}

当上面的代码被编译和执行时,它会产生下列结果:

最大值是: 200

上面展示的是在当前类的内部实例化并调用方法,其实也可以在另一个类中实例化并调用其他类的公有方法。


2、方法的递归调用

方法不仅可以在类之间互相调用,而且可以自我调用,这就是所谓的递归。下面的实例使用递归函数计算一个数的阶乘:

using System;

namespace CalculatorApplication
{
    class NumberManipulator
    {
        public int factorial(int num)
        {
            /* 局部变量定义 */
            int result;

            if (num == 1)
            {
                return 1;
            }
            else
            {
                result = factorial(num - 1) * num;  //递归调用factorial方法
                return result;
            }
        }
   
        static void Main(string[] args)
        {
            NumberManipulator n = new NumberManipulator();
            //调用 factorial 方法
            Console.WriteLine("6 的阶乘是: {0}", n.factorial(6));
            Console.WriteLine("7 的阶乘是: {0}", n.factorial(7));
            Console.WriteLine("8 的阶乘是: {0}", n.factorial(8));
            Console.ReadLine();

        }
    }
}

当上面的代码被编译和执行时,它会产生下列结果:

6 的阶乘是: 720
7 的阶乘是: 5040
8 的阶乘是: 40320


3、方法的参数传递

当调用带有参数的方法时,您需要向方法传递参数。在 C# 中,有三种向方法传递参数的方式:

方式 描述
值参数 这种方式复制参数的实际值给函数的形式参数,实参和形参使用的是两个不同内存中的值。在这种情况下,当形参的值发生改变时,不会影响实参的值,从而保证了实参数据的安全。
引用参数 这种方式复制参数的内存位置的引用给形式参数。这意味着,当形参的值发生改变时,同时也改变实参的值。
输出参数 这种方式同样也复制参数的内存位置的引用给形式参数,区别在于该参数不需要初始化赋值。

3.1 按值传递参数

这是参数传递的默认方式。在这种方式下,当调用一个方法时,会为每个值参数创建一个新的存储位置。

实际参数的值会复制给形参,实参和形参使用的是两个不同内存中的值。所以,当形参的值发生改变时,不会影响实参的值,从而保证了实参数据的安全。下面的实例演示了这个概念:

using System;
namespace CalculatorApplication
{
   class NumberManipulator
   {
      public void swap(int x, int y)
      {
         int temp;
         
         temp = x; /* 保存 x 的值 */
         x = y;    /* 把 y 赋值给 x */
         y = temp; /* 把 temp 赋值给 y */
      }
     
      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* 局部变量定义 */
         int a = 100;
         int b = 200;
         
         Console.WriteLine("在交换之前,a 的值: {0}", a);
         Console.WriteLine("在交换之前,b 的值: {0}", b);
         
         /* 调用函数来交换值 */
         n.swap(a, b);
         
         Console.WriteLine("在交换之后,a 的值: {0}", a);
         Console.WriteLine("在交换之后,b 的值: {0}", b);
         
         Console.ReadLine();
      }
   }
}

当上面的代码被编译和执行时,它会产生下列结果:

在交换之前,a 的值:100
在交换之前,b 的值:200
在交换之后,a 的值:100
在交换之后,b 的值:200

结果表明,即使在函数内改变了值,值也没有发生任何的变化。

3.2 按引用传递参数——ref关键字

引用参数是一个对变量的内存位置的引用。当按引用传递参数时,与值参数不同的是,它不会为这些参数创建一个新的存储位置。引用参数表示与提供给方法的实际参数具有相同的内存位置。

在 C# 中,使用 ref 关键字声明引用参数。下面的实例演示了这点:

using System;
namespace CalculatorApplication
{
   class NumberManipulator
   {
      public void swap(ref int x, ref int y)
      {
         int temp;

         temp = x; /* 保存 x 的值 */
         x = y;    /* 把 y 赋值给 x */
         y = temp; /* 把 temp 赋值给 y */
       }
   
      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* 局部变量定义 */
         int a = 100;
         int b = 200;

         Console.WriteLine("在交换之前,a 的值: {0}", a);
         Console.WriteLine("在交换之前,b 的值: {0}", b);

         /* 调用函数来交换值 */
         n.swap(ref a, ref b);

         Console.WriteLine("在交换之后,a 的值: {0}", a);
         Console.WriteLine("在交换之后,b 的值: {0}", b);
 
         Console.ReadLine();

      }
   }
}

当上面的代码被编译和执行时,它会产生下列结果:

在交换之前,a 的值:100
在交换之前,b 的值:200
在交换之后,a 的值:200
在交换之后,b 的值:100

结果表明,swap 函数内的值改变了,且这个改变可以在 Main 函数中反映出来。

3.3 按输出传递参数——out关键字

提供给输出参数的变量不需要初始化赋值,其他方面与引用参数相似。当需要从一个参数没有指定初始值的方法中返回值时,输出参数特别有用。请看下面的实例,来理解这一点:

using System;

namespace CalculatorApplication
{
   class NumberManipulator
   {
      public void getValues(out int x, out int y )
      {
          Console.WriteLine("请输入第一个值: ");
          x = Convert.ToInt32(Console.ReadLine());
          Console.WriteLine("请输入第二个值: ");
          y = Convert.ToInt32(Console.ReadLine());
      }
   
      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* 局部变量定义 */
         int a , b;
         
         /* 调用函数来获取值 */
         n.getValues(out a, out b);

         Console.WriteLine("在方法调用之后,a 的值: {0}", a);
         Console.WriteLine("在方法调用之后,b 的值: {0}", b);
         Console.ReadLine();
      }
   }
}

当上面的代码被编译和执行时,它会产生下列结果(取决于用户输入):

请输入第一个值:
7
请输入第二个值:
8
在方法调用之后,a 的值: 7
在方法调用之后,b 的值: 8

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

unity的C#学习——方法的定义、调用、递归与参数传递 的相关文章

随机推荐

  • 剑指Offer第三十六题:两个链表的第一个公共结点

    题目描述 输入两个链表 找出它们的第一个公共结点 思路 这里两个单向链表如果有公共结点肯定是下面这种情况 最后通过公共结点汇合 1 看到这题我直接想到哈希 直接利用map存储一个链表 第二个链表遍历查找地址即可 2 链表的叠加 如下图 假设
  • 前沿技术创新是人工智能发展的动力之源 不断拓展能力边界

    近日 WAIC2022上海人工智能开发者大会在中国 上海 自由贸易试验区临港新片区举行 记者从会上获悉 上海将加大力度推动算法开源 数据开放 算力开发 与国内外知名开源社区互联互通 打造国际人工智能开发生态网络的关键节点 前沿技术创新是人工
  • shell脚本之 函数——【初学者必看】

    shell脚本之函数 一 shell函数定义 1 1函数注意事项 1 2 函数返回值 1 3函数调用的方法 1 4 函数的传参 1 5 函数的作用范围 1 6函数的参数 1 6 1参数的用法 1 6 2参数的表示方法 1 6 3 经典案例
  • Flutter实战Align使用详解

    Align相关属性 Align Key key this alignment Alignment center this widthFactor this heightFactor Widget child alignment 需要一个Al
  • 关于C++中unsigned类型

    我们知道c 中的long long 也知道c 里long long有符号 unsigned long long和long long的区别就在于 1 unsigned long long 没有符号 表示范围是0到264 1 2 long lo
  • Java实现Kafka生产者和消费者的示例(1),mysqlsql语句面试题

    RecordMetadata recordMetadata null try 将消息发送到Kafka服务器的名称为 one more topic 的Topic中 recordMetadata kafkaProducer send new P
  • liboqs-go库在Mac编译使用

    liboqs go库在Mac编译使用 liboqs go是liboqs 量子安全密码算法的开源C库的go封装 将在mac m1上部署和开发使用 所以简单记录下过程 部署 安装基础依赖工具 brew install cmake ninja o
  • Python3,5行代码,Chatxxx能对PDF文件进行旋转、提取、合并等一系列操作,看了这篇,80岁老奶奶走路都不扶墙了。

    ChatPDF的妙用 1 引言 2 代码实战 2 1 原理 2 2 安装 2 2 示例 2 2 1 创建PDF文件 2 2 2 旋转PDF文件 2 2 3 拆分PDF文件 2 2 4 合并PDF文件 2 2 5 提取PDF文件内容 3 总结
  • Linux编译器

    Vi是LINUX系统的第一个全屏幕交互式编译工具 vi的查找与替换 lt 要查找的字符 gt 向下查找要找查的字符 lt 要查找的字符 gt 向上查找要找查的字符 range s string1 string2 gc 替换 例如 10 20
  • 读书笔记----《编写高质量代码:改善Java程序的151个建议》第八/九章

    读书笔记 编写高质量代码 改善Java程序的151个建议 第八 九章 第八章 异常 110 提倡异常封装 111 采用异常链传递异常 112 受检异常尽可能转化为非受检异常 113 不要在finally块中处理返回值 114 不要在构造函数
  • MySQL - 表字段的自增约束

    设置表字段值自动增加 AUTO INCREMENT AUTO INCREMENT是MySQL唯一扩展的完整性约束 当向数据库表中插入新记录时 字段上的值会自动生成唯一的ID 在具体设置AUTO INCREMENT约束时 一个数据库表中只能有
  • 【Unity 3D】VR飞机动态拆装及引擎开关控制案例(附源码和演示视频 超详细)

    需要源码和资源包请点赞关注收藏后评论区留言私信 上一篇博客介绍了如何搭建飞机场景 制作了飞机引擎开启喷射火焰 并且让飞机起飞了参考链接如下 飞机场景搭建 一 效果展示 其中按空格可以控制后部引擎开关 即喷火和不喷火 演示视频如下 拆装飞机控
  • 仿微信 QQ聊天界面,弹出软键盘,listview上移,标题不动

    转载请注明出处 http blog csdn net ym4189 article details 79568820 完美解决聊天布局 顶部title固定 底部是EditText 中间是ListView 弹出软键盘 ListView上移 标
  • JAVA中的基本数据类型和包装类

    8大基本数据类型 byte byte 8位 存放的数据范围是 128 127之间 默认值为0 short short 16位 数据范围是 32768 32767之间 默认值为0 int int 32位 数据范围是 2 31 2 31 1 默
  • Unity3D 屏幕点击特效

    前言 屏幕点击特效目前用到两种 场景中特效和UI特效 其实就是坐标和层级之间的区别 无论特效用的帧动画 粒子特效亦或是贴图都可以使用 根据项目稍微调整下就好了 如果想优化的话可以写个对象池 这里就不赘述了 1 UI点击特效 注意要将Laye
  • java—手机号脱敏

    Java中手机号脱敏是指将真实手机号码中的一部分数字用特定字符替换 以保护用户的个人信息 通常 手机号码脱敏会将手机号的中间几位或者最后几位替换成特定字符 例如用 X 或者其他随意选择的字符来代替 手机号脱敏的目的是防止用户个人信息外泄 在
  • leetcode——探索字节跳动系列题目

    今天登陆leetcode发现探索区多了字节跳动的专栏 特意用了一下午去刷 有些是之前刷过的 但题目不错 就当是复习一遍吧 这里记录一下我会的以及自己觉得不错的题目 原题链接请点击题目 一 挑战字符串 3 无重复字符的最长子串 分析 这题要求
  • library()加载问题解决

    Rstudio中 在加载包 访问时遇到以下问题 trying URL https mirrors tuna tsinghua edu cn CRAN bin windows contrib 3 6 tseries 0 10 47 zip C
  • excel vlookup多个条件匹配多列_Excel数据多条件交叉查询,全部3种方法都在这,vlookup函数已经out了...

    Excel进行数据查询 相信许多人都会说一个函数 那就是vlookup函数 许多人会把这个函数当做Excel函数中的NO 1 毋庸置疑在Excel数据匹配的时候 单条件数据查找vlookup的功能确实是非常的强大 但是在进行数据多条件查询的
  • unity的C#学习——方法的定义、调用、递归与参数传递

    文章目录 C 方法 1 方法的定义与调用 2 方法的递归调用 3 方法的参数传递 3 1 按值传递参数 3 2 按引用传递参数 ref关键字 3 3 按输出传递参数 out关键字 C 方法 一个方法是把一些相关的语句组织在一起 用来执行一个