C# 方法(参数数组)

本章内容:

方法的结构

方法体内部的代码执行

局部变量

局部常量

控制流

方法调用

返回值

返回语句和void方法

局部函数

参数

值参数

引用参数

引用类型作为值参数和引用参数

输出参数

参数数组

参数类型总结

方法重载

命名参数

可选参数

栈帧

递归

参数数组

至此,在本书所述的参数类型中,一个形参必须严格地对应一个实参。参数数组则不同,它

允许特定类型的零个或多个实参对应一个特定的形参。参数数组的重点如下。

在一个参数列表中只能有一个参数数组。

如果有,它必须是列表中的最后一个。

由参数数组表示的所有参数必须是同一类型。

声明一个参数数组时必须做的事如下。

在数据类型前使用params修饰符。

在数据类型后放置一组空的方括号。

下面的方法头展示了int型参数数组的声明语法。在这个示例中,形参inVals可以代表零

个或多个int实参。

类型名后面的空方括号指明了参数是一个整数数组。在这里不必在意数组的细节,它们将在

第13章详细阐述。而现在,你需要了解的内容如下。

数组是一组有序的同一类型的数据项。

数组使用一个数字索引进行访问。

数组是一个引用类型,因此它的所有数据项都保存在堆中。

方法调用

可以使用两种方式为参数数组提供实参。

  • 一个用逗号分隔的该数据类型元素的列表。所有元素必须是方法声明中指定的类型。
csharp 复制代码
ListInts(10,20,30)   //3个int
  • 一个该数据类型元素的一维数组。
csharp 复制代码
int[] intArray={1,2,3};
ListInts(intArray);    //一个数组变量

请注意,在这些示例中,没有在调用时使用params修饰符。参数数组中修饰符的使用与其

他参数类型的模式并不相符。

  • 其他参数类型是一致的,要么都使用修饰符,要么都不使用修饰符。
    • 值参数的声明和调用都不带修饰符。
    • 引用参数和输出参数在两个地方都需要修饰符。
  • params修饰符的用法总结如下。
    • 在声明中需要修饰符。
    • 在调用中不允许有修饰符。

延伸式

方法调用的第一种形式有时被称为延伸式 ,这种形式在调用中使用独立的实参。

例如,下面代码中的方法ListInts的声明可以匹配其后所有的方法调用,虽然它们的实参

数目不同。

csharp 复制代码
void ListInts(params int[] inVals) //方法声明
{
    ....
}

...
ListInts();                        //0个实参
ListInts(1,2,3);                   //3个实参
ListInts(4,5,6,7);                 //4个实参
ListInts(8,9,10,11,12)             //5个实参

在使用一个为参数数组使用独立实参的调用时,编译器做下面几件事。

  • 接受实参列表,用它们在堆中创建并初始化一个数组。
  • 把数组的引用保存到栈中的形参里。
  • 如果在对应形参数组的位置没有实参,编译器会创建一个有零个元素的数组来使用。
    例如,下面的代码声明了一个名为ListInts的方法,它接受有一个参数数组。Main声明了
    3个整数并把它们传给了数组。
csharp 复制代码
class MyClass
{
    public void ListInts(params int[] inVals) //参数数组
    {
        if((inVals!=null)&&(inVals.Length!=0))
        {
            for(int i=0;i<inVals.Length;i++)//处理数组
            {
                inVals[i]=inVals[i]*10;
                Console.WriteLine($"{inVals[i]}");//显示新值
            }
        }
    }
}

class Program
{
    static void Main()
    {
        int first=5,second=6,third=8;  //声明3个int

        MyClass mc=new MyClass();
        mc.ListInts(first,second,third);//调用方法 实参

        Console.WriteLine($"{first},{second},{thrid}");
    }
}

图6-12阐明了在方法执行的不同阶段实参和形参的值。

  • 方法调用之前,3个实参已经在栈里。

  • 在方法的开始,3个实参被用于初始化堆中的数组,并且数组的引用被赋值给形参

    inVals。

  • 在方法内部,代码首先检查以确认数组引用不是null,然后处理数组,把每个元素乘以

    10并保存回去

  • 方法执行之后,形参inVals失效。

    关于参数数组,需要记住的一点是当数组在堆中被创建时,实参的值被复制到数组中。这样,

    它们像值参数。

  • 如果数组参数是值类型,那么值被复制,实参在方法内部不受影响。

  • 如果数组参数是引用类型,那么引用被复制,实参引用的对象在方法内部会受到影响。

将数组作为实参

也可以在方法调用之前创建并组装一个数组,把单一的数组变量作为实参传递。这种情况下,

编译器使用你的数组而不是重新创建一个。

例如,下面的代码使用前一个示例中声明的方法ListIntso在这段代码中,Main创建一个

数组,并用数组变量而不是使用独立的整数作为实参。

复制代码
static void Main()
{
    int[] myArr=new int[]{5,6,7};//创建并初始化数组
    MyClass mc=new MyClass();    
    mc.ListInts(myArr);          //调用方法来打印值

    foreach(int x in myArr)
        Console.WriteLien($"{x}");//输出每个元素
}

参数类型总结

因为有4种参数类型,所以有时很难记住它们的不同特征。表6-2对它们做了总结,以便于

比较和对照。

相关推荐
leoZ2313 分钟前
本地跑大模型实战(七):llama.cpp 性能调优,让推理更快更省
java·人工智能·spring·生成对抗网络·语言模型·自然语言处理·llama
mubei-1232 小时前
SpringDAO的用法
java·开发语言·数据库
happymagic2 小时前
java spring boot做的jar包程序,如何实现自动运行启动
java·运维·服务器·spring boot·jar
小程故事多_802 小时前
从A2C、TRPO、PPO到GRPO,强化学习策略梯度算法完整演进与大模型落地实战解析
人工智能·算法
2601_956121974 小时前
二分算法(知识点+题目)
c++·算法
都叫我大帅哥4 小时前
给 Java 程序员的 CSRF 攻击详解:从原理到防御实战
java
江南十四行4 小时前
Spring框架核心(上)——IoC控制反转与DI依赖注入详解
java·后端·spring
fb_123455 小时前
Linux磁盘分区从入门到实操:MBR_GPT全解析+分区工具实战指南
java·linux·gpt
码智社6 小时前
JSON 零基础到资深全体系教程
java·json
AndrewHZ6 小时前
【LLM技术全景】阶段总结:技术原理篇核心知识回顾
人工智能·深度学习·算法·语言模型·大模型·llm·芯片开发