C 语言 作用域规则
在任何一种编程中,作用域都是用来规定变量所存在的区域,超过该区域变量就不能被访问。
C 语言中有三个地方可以声明变量:
-
函数内部或者块内部的 局部 变量
-
在所有函数外部的 全局 变量
-
函数 形式参数的定义的 形式参数 变量
我们先来看看什么是 局部 变量、 全局 变量和 形式 参数。
局部变量
在某个函数内部或块的内部声明的变量称为局部变量。
局部变量只能被该函数或该代码块内部的语句使用。
局部变量在函数外部是不可知的。
让我们来看一个 局部变量 的实例。
范例: 局部变量的可见范围
在这里,所有的变量 a、b 和 c 是 main() 函数的局部变量。
/** * file: main.c * author: 简单教程(www.twle.cn) */ #include <stdio.h> void local_var() { /* 局部变量声明 */ int a, b; int c; /* 实际初始化 */ a = 17; b = 13; c = a + b; printf ("value of a = %d, b = %d and c = %d\n", a, b, c); } int main () { local_var(); //printf("访问 local_var 函数中定义的变量会出错 %2d\n", c); return 0; }
编译和运行上面的范例,输出结果如下
$ gcc main.c && a.out value of a = 17, b = 13 and c = 30
但如果把 //printf("访问 local_var 函数中定义的变量会出错 %2d\n", c);
注释去掉,编译时就会报错
$ gcc main.c && a.out main.c:28:71: error: use of undeclared identifier 'c' printf("访问 local_var 函数中定义的变量会出错 %2d\n", c); ^ 1 error generated.
全局变量
全局变量是定义在函数外部,通常是在程序的顶部。
全局变量在整个程序生命周期内都是有效的,在任意的函数内部能访问全局变量。
全局变量可以被任何函数访问。 也就是说,全局变量在声明后整个程序中都是可用的。
我们来看一个使用全局变量和局部变量的范例
/** * file: main.c * author: 简单教程(www.twle.cn) */ #include <stdio.h> /* 函数声明区域 */ void local_var(); /* 全局变量声明 */ int cnt = 7; int main () { /* 局部变量声明 */ int a, b; /* 实际初始化 */ a = 17; b = 13; cnt = a + b; local_var(); printf ("value of a = %d, b = %d and cnt = %d\n", a, b, cnt); return 0; } void local_var() { cnt ++; printf ("输出全局变量 cnt: %2d\n",cnt); }
编译和运行上面的代码,输出结果如下
$ gcc main.c && a.out 输出全局变量 cnt: 31 value of a = 17, b = 13 and cnt = 31
在程序中,局部变量和全局变量的名称可以相同,但是在函数内,局部变量的值会覆盖全局变量的值。
我们看一个局部变量覆盖全局变量的例子
/** * file: main.c * author: 简单教程(www.twle.cn) */ #include <stdio.h> /* 函数声明区域 */ void local_var(); /* 全局变量声明 */ int cnt = 7; int main () { /* 局部变量声明 */ int a, b; /* 实际初始化 */ a = 17; b = 13; cnt = a + b; local_var(); printf ("value of a = %d, b = %d and cnt = %d\n", a, b, cnt); return 0; } void local_var() { int cnt = 7; cnt ++; printf ("输出变量 cnt: %2d\n",cnt); }
编译和运行上面的范例,输出结果如下
$ gcc main.c && a.out 输出变量 cnt: 8 value of a = 17, b = 13 and cnt = 30
在 local_var()
函数中的局部变量 cnt
覆盖了全部变量 cnt
,那么对 cnt
的修改就不会影响到全局的 cnt 。
形式参数
函数的参数,形式参数,被当作该函数内的局部变量,它们会优先覆盖全局变量。
范例: 函数形参覆盖全局变量
/** * file: main.c * author: 简单教程(www.twle.cn) */ #include <stdio.h> /* 函数声明区域 */ void local_var(int cnt); /* 全局变量声明 */ int cnt = 7; int main () { /* 局部变量声明 */ int a, b; /* 实际初始化 */ a = 17; b = 13; cnt = a + b; local_var(cnt); printf ("value of a = %d, b = %d and cnt = %d\n", a, b, cnt); return 0; } void local_var(int cnt) { cnt ++; printf ("输出变量 cnt: %2d\n",cnt); }
编译和运行上面的代码,输出结果如下
$ gcc main.c && a.out 输出变量 cnt: 31 value of a = 17, b = 13 and cnt = 30
局部变量和全局变量的初始化
当局部变量被定义时,系统不会对其初始化,您必须自行对其初始化。 定义全局变量时,系统会自动对其初始化。
全局变量默认初始化值如下:
数据类型 | 初始化默认值 |
---|---|
int | 0 |
char | '\0' |
float | 0 |
double | 0 |
pointer | NULL |
最佳实战
正确地初始化变量是一个良好的编程习惯,否则有时候程序可能会产生意想不到的结果,因为未初始化的变量会导致一些在内存位置中已经可用的垃圾值。