参数
函数的参数
- 为了保证代码的灵活性,可以将代码中变化的部分提取出来,用变量代替。
void Say() { int count = 3; // 这时如果想实现重要的话说4遍,只需要将count的值改为4。 for(int i = 0; i < count; i ++) { Console.WriteLine("重要的话说" + count + "遍:李康是帅哥!"); } }
- 在函数内申明的变量叫局部变量,只能在该函数内部访问。
- 局部变量只能在函数内访问,无法从外部给它赋值。
参数是一种特殊的局部变量,在函数的参数列表中申明,它可以通过函数的调用,从外部给参数赋值。
static void Main(string[] args) { Say(3); // 这时3会赋值给Say函数的参数count。 } static void Say(int count) // 参数可以在函数调用时,通过外部赋值。 { //int count = 3; // count只能在Say函数内部赋值。 for (int i = 0; i < count; i++) { Console.WriteLine("重要的话说" + count + "遍:李康是帅哥!"); } }
- 一个函数可以有多个参数。
调用函数时传参的个数和顺序要与函数的定义一致。
static void Main(string[] args) { Say(3, "李康是帅哥!"); // OK: 说3遍"李康是帅哥!" // Say; // ERROR: 函数调用必需加() // Say(3); // ERROR: 参数个数与定义不一致。 // Say("李康是帅哥!", 3); // ERROR: 参数的顺序与定义不一致。这里相当于把"李康是帅哥!"赋值给了int变量count。 } static void Say(int count, string msg) // 参数可以在函数调用时,通过外部赋值。 { //int count = 3; // count只能在Say函数内部赋值。 for (int i = 0; i < count; i++) { Console.WriteLine("重要的话说" + count + "遍:\"" + msg +"\""); } }
- 参数使得函数在模块化的同时,保证了模块的灵活性。
形参与实参
- 函数定义中的参数是形参。
- 函数调用中的参数是实参。
- 形参是一个变量申明。
实参是一个数据,这个数据可以是一个常量数值,也可以是一个变量。
static void Main(string[] args) { Say(3); // 3是实参 int count = 3; Say(count); // count是实参,但这个count和函数定义中的形参count是两个不同的变量。 } static void Say(int count) // count是形参 { for (int i = 0; i < count; i++) { Console.WriteLine("重要的话说" + count + "遍:\"李康是帅哥!\""); } }
局部变量与全局变量
- 局部变量是在函数内申明的变量,只能在该函数内访问。
- 全局变量是在函数外(
class
内)申明的变量,可以在所有函数内访问。 - 参数是一种特殊的局部变量,但可以通过函数调用给参数赋值。
- 局部变量与全局变量同名时,使用就近原则,访问的是局部变量。
int a = 1; // 定义了全局变量a void Fun() { int a = 2; // 定义了同名的局部变量a Console.WriteLine(a);// 输出:2 }
- 局部变量必需先赋值才能使用。
- 全局变量可不赋值使用,全局变量有默认值。
变量的作用域
- 变量的作用域指在哪个范围内能访问这个变量。
- 变量的作用域通常是从申明开始到包含它的那对
{}
结束。(这句话不是非常准确,但好理解。) 要注意
if
的局部变量和switch
中的局部变量。class Program { // global是全局变量,在包裹它的class{}中都可以访问。 int global = 100; void Fun() { // a是函数的局部变量,只能在包裹它的这个函数中访问。 int a = 1; for(int i = 0; i < 10; i++) // i是for循环的局部变量,只能在包裹它的for循环中访问。 { } // 这里就访问不到上面的i了 for(int i = 0; i < 5; i++) // 这个i和之前的i不冲突,因为作用域不一样。 { } switch(a) { case 0: int b = 1; break; case 1: // int b = 2; // ERROR: 上面那个case中已经定义了b变量。它们的作用域都是包裹它的switch{}。 break; } } }
代码块
- 可以独立的使用代码块
{}
来定义一个作用域。static void Main(string[] args) { // 这是一个代码块 { int a = 1; // a的作用域在包裹它的这对{}里。 Console.WriteLine(a); } //Console.WriteLine(a); // ERROR: 这里访问不到变量a了。 }
switch
中可以使用代码块解决各个case中的变量冲突。static void Main(string[] args) { string input = Console.ReadLine(); switch (input) { case "w": { // 加入了代码块 int a = 1; break; } case "s": { // 加入了代码块 int a = 1; // OK: 这两个变量a的作用域不冲突 break; } } }
变量的生命周期
- 变量的生命周期用来说明变量从什么时候产生,到什么时候销毁。
- 变量只能通过申明产生。
int a; // 变量产生了
- 当程序执行到变量作用域之外时,变量就会被销毁。
- 变量产生时会分配对应大小的内存,消亡时会回收这块内存。
- 变量消亡后,其存储的数据就一同消亡了。
- 变量的生命周期与作用域通常是一致的。只不过他们一个是时间概念,一个是空间概念。
C#
是一种托管内存的编程语言,所以变量的生命周期的概念就不重要了,了解一下就行。