C语言中的函数-全局变量和局部变量-学习笔记-19

引入

我们之前说过变量,可以改变的量即变量,变量还拥有很多种类型,但今天我们要说的是全局变量和局部变量。出了变量类型、变量名、变量的值还有就是变量的作用范围,根据作用范围不同,我们将变量分为全局变量局部变量两种。
由于之前我们写的程序基本上都在 main 函数中,并且变量一般都在函数开头的地方定义,因为变量要先声明再使用,在 main 函数中的变量,或者说在函数开头声明的变量,只在该函数内有效,也就是只能在该函数内引用
那么如果我们需要一个变量,能够在多个函数间使用呢?这就引出了变量作用域这个问题了。

三种定义变量的情况

我们线回顾一下,定义变量时,一般有如下三种情况:

  1. 在函数开头处定义,这是我们最常用的
  2. 在函数内的复合语句内定义,例如 for 语句的计次变量
  3. 在函数的外部定义。

    局部变量

    函数的内部定义的变量,只在函数内部有效。也就是说只有在本函数内,我们才能对它进行赋值、引用等操作。
    复合语句中定义的变量,只有在该复合语句内有效,只有在本复合语句中才能引用
    所以,我们称上面这两种为局部变量

    举例

1
2
3
4
5
int num(int a){
int b,c;
// a、b、c 在这个 num 函数中都是有效的
...
}

上面我们定义了一个 num 函数,函数有一个形参 a,函数内有两个变量 b 和 c,a、b、c在这个 num 函数中都有合法有效的。

1
2
3
4
5
int average(int a, int b){
int c;
// a、b、c 在这个 average 函数中都是有效的
...
}

上面我们定义了一个 average 函数,函数有两个形参 a 和 b,函数内部声明了一个变量 c,此时 a、b、c 在 average 函数中都是有效的。

1
2
3
4
5
int main(){
int a,b,c;
// a、b、c 在这个 main 函数中都是有效的
...
}

上面是我们最常见的 main 函数,但是哪怕是 main 函数,在 main 函数中定义的变量, 也只在 main 函数中有效,跨函数是无法直接调用的。

1
2
3
4
5
6
7
for(int i=0;i<3;i++){
for(int i=0;i<4;i++){
if (bignum[i][i]>big){
big=bignum[i][i];
}
}
}

上面是包含在函数中的复合语句,虽然里面我们定义了两个 i,但是因为是不同的复合语句,所以外部的 for 循环的 i 是没法调用内部 for 循环的 i 的。这样写虽然合法,但是我们不推荐,因为变量名相同, 很容易混淆,给以后的程序维护增加麻烦。

总结

  1. 主函数中的变量也只在主函数中有效,相应的,主函数也不能调用其他函数内声明的变量,变量只在声明它的函数内有效
  2. 不同的函数中的变量,变量名可以相同。例如上面都是哪 a、b、c 三个变量来举例子,但是这三个变量实际上是在不同的内存单元,互不干扰。
  3. 有参函数中的形式参数是局部变量。例如上面前两个都是有参函数,但这些形参也只在该函数内有效。
  4. 在一个函数内部,可以包含复合语句,复合语句中定义的变量,也只在该复合语句中有效。例如在 for 循环中,我们定义的用于计数的比如 i ,在 for 循环外是不能使用的。

全局变量

前面说过,程序编译的单位是源程序文件,一个源程序文件包含一个或多个函数,在函数内定义的变量是局部变量,在函数的外部定义的变量,我们称之为外部变量,外部变量是一种全局变量
该变量可以为本文件内的其他所有函数所公用,它的有效范围为从定义该变量开始到该源文件最末尾结束

举例

1
2
3
4
5
6
7
8
9
10
int a;
int main(){
int b;
}
//在 main 函数中 a、b有效
int z;
int average(int c){
int d;
}
// 在 average 函数中 a、c、d、z有效

这里我们定义了两个全局变量 a 和 z,但是 main 函数中 z 是无效的。我们可以理解为,在函数外申明的变量 a,在其下方的所有函数中都是合法有效的。

例题

有一个一维数组,输入10个学生成绩,main 函数调用一个函数,可以返回这10个学生成绩的最大值、最小值和平均值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
float Max,Min;
int main(){
float average(float score[10],int k);
float studentScore[10];
int i;
printf("请输入学生成绩:\n");
for(i=0;i<10;i++){
scanf("%f",&studentScore[i]);
}
printf("10个学生的平均成绩是:%2.1f,最大值是:%2.1f,最小值是:%2.1f\n",average(studentScore,10),Max,Min);
return 0;
}

float average(float score[10],int k){
float average=0;
Max=Min=score[0];
for (int i=0;i<10;i++){
if(Max<score[i]){
Max=score[i];
}else if(Min>score[i]){
Min=score[i];
}
average=average+score[i];
}
return (average/k);
}

其中 Max 和 Min 是两个全局变量,所以我们可以在 main 函数和 average 函数中使用他们。

不过,我们建议,在不必要时,不要使用全局变量,原因如下:

  1. 全局变量不是在使用时才占用存储空间,而是在全部的执行过程中都要占用存储空间。
  2. 全局变量的使用,使得函数的通用性降低了,如果函数需要一直到另一个源文件中,还要考虑其引用的全局变量。并且我们建议函数的功能性越单一约好,只通过实参-形参这种形式传递数据,然后函数可以放到任何地方处理我们需要的数据。
  3. 大量使用全局变量,会降低人们在程序执行到某一时刻时,变量值的理解,降低程序运行时的清晰度。

如果全局变量和局部变量名冲突该如何处理?

  1. 出错
  2. 局部变量无效,全局变量有效
  3. 在局部变量作用范围内,局部变量有效,全局变量不起作用

尾巴

这是我的个人学习笔记,主要是应付考研复习使用,充斥着一些吐槽和个人观点,并不严谨,欢迎大家参考、指正。


-------------The End-------------
欢迎请我喝咖啡哦~!