【C语言入门教程】5.2 函数的作用域规则(auto, static)
作用域规则是指代码或数据的有效使用范围。C语言将函数作为独立的代码块,函数之间不能相互访问其内部的代码或数据。函数间数据的传递只能通过接口实现。但是,变量的定义方法可改变函数的作用域规则,可将变量分为 局部变量 和 全局变量 两种。
5.2.1 局部变量
在函数体内定义的变量称为 局部变量,局部变量的作用域仅限于该函数体内。声明局部变量的关键字为 auto,它的一般形式是:
auto 数据类型 变量名;
auto 关键字作为声明语句的默认值,所以通常省略。在函数中定义的局部变量,作用域在该函数体内,如:
void func() { int x = 1000; printf("func()函数内的变量 x 值为:%d\n", x); // 输出为 func() 函数体内变量 x 的值 } int main() { int x = 2000; func(); printf("main() 函数内的变量 x 值为:%d\n", x); // 输出 main() 函数体内变量 x 的值 return 0; }
func()函数 和 main() 函数各自定义了一个变量 x,在 func()函数中访问变量 x,则访问的是func()函数体内所定义的变量x。同理,main()函数只能访问其函数体内的变量x。这样,不同函数间的数据被独立起来,保证了数据的安全性。上例的输出为:
func()函数内的变量 x 值为:1000
main()函数内的变量 x 值为:2000
在独立的代码块内定义的局部变量,作用域在该代码块内,如下例所示:
int main() { int x = 100; if (x < 150) // 这里引用的是main() 函数中定义的变量 x { int x = 200; // 在代码块中定义变量 x printf("%d", x); // 这里引用的是代码块中定义的变量 x } return 0; }
该程序输出的结果为 200,因为引用的是代码块中的变量x。如果去掉代码快中定义变量x的语句,那么输出的将是 main() 函数的变量x,输出结果为 100。假设在变量的一个作用域内,有同名的另一个变量的作用域,只有一个变量是有效的。如图 9.1 所示,作用域2被包含在作用域1内,2个作用域都定义了变量x。简单地说,定义位置与引用位置相近的变量是有效的,即作用域2内定义的变量x被引用。
5.2.2 全局变量
全局变量的作用域为整个源程序文件,文件中的所有函数或程序块都可以引用。当定义全局变量时,需将变量声明语句放置在所有函数外,如:
#include <stdio.h> int x = 1000; void func(); int main() { printf("%d\n", x); // 引用全局变量 x x = 2000; // 改变全局 x 的值 func(); // 调用函数 func() return 0; } void func() { printf("%d\n", x); // 引用全局变量 x,此时全局变量 x 的值已被 main() 函数改变过 return; }
5.2.3 动态存储变量
从变量的生存周期来分类,可将变量分为 动态存储变量 和 静态存储变量。动态存储变量在函数调用时存入内存,函数调用后从内存中删除。声明动态存储变量的关键字为 auto,与声明局部变量相同,它的一般形式是:
auto 数据类型 变量名;
auto 关键字作为声明语句的默认值,所以通常可省略。由于函数中的动态变量会在函数退出时删除,所以两次调用函数时,函数不会保存动态变量的数据。如下例所示:
#include <stdio.h> void func() { int x = 100; printf("%d\n", x); x += 100; } int main () { func(); func(); return 0; }
此程序2次输出的值都是 100.因为即使func()函数第一次调用时改变了变量 x 的值,函数退出后变量x 被从内存中删除,第二次调用函数时又需要重新初始化 x ,所以2次输出的值相同。
还有一种动态存储变量称之为 寄存器变量,寄存器是位于 CPU 内部的存储单元,CPU读取寄存器内的数据极其快捷。因此,将程序中需要大量反复使用的变量设为寄存器变量可提高程序的运行速度。声明寄存器变量
的一般形式为:
register 数据类型 变量名;
寄存器资源非常有限,不同的操作系统 和 C 编译器对寄存器变量的使用有不同的限制。如 GCC 编译器通常限制寄存器变量的数量为 2个,将超过的寄存器变量当做普通动态变量处理。
5.2.4 静态存储变量
在编译时分配存储空间的变量称为静态存储变量。在函数退出时,静态存储变量依然被保留在内存中,再次执行同一函数会得到与上次退出时相同的数值。声明静态存储变量的关键字为 static,声明的一般形式为:
static 数据类型 变量名;
如下代码所示:
#include <stdio.h> void func() { static int x = 100; // 声明静态存储变量 x 并赋初值 printf("%d\n", x); // 输出 x 的值,此时变量 x 的值为 100 x += 100; // 改变 x 的值,此时变量 x 的值为 200 } int main () { func(); // 第一次调用函数 func() func(); // 第二次调用函数 func() return 0; }
第一次调用 func() 函数时,声明了静态存储变量 x,并为变量 x 赋初值 100,然后输出变量 x 的值,将变量 x 的值加上 100。func()函数退出后变量 x 仍然存在于内存中,所以第二次调用 func() 函数时,声明变量 x 并赋初值的语言不会被再次执行,因而第二次输出变量的值为 200。