| C语言变量的作用域和存储类型 |
|
作者:北极圈 文章来源:本站整理 点击数: 更新时间:2008-6-18 14:08:16 |
|
一、作用域和生存期 C程序的标识符作用域有三种:局部、全局、文件。标识符的作用域决定了程序中的哪些语句可以使用它,换句话说,就是标识符在程序其他部分的可见性。通常,标识符的作用域都是通过它在程序中的位置隐式说明的。 1.局部作用域 前面各个例子中的变量都是局部作用域,他们都是声明在函数内部,无法被其他函数的代码所访问。函数的形式参数的作用域也是局部的,它们的作用范围仅限于函数内部所用的语句块。
void add(int);
main() { int num=5; add(num); printf(%d\n,num); /*输出5*/ }
void add(int num) { num++; printf(%d\n,num); /*输出6*/ }
上面例子里的两个num变量都是局部变量,只在本身函数里可见。前面我们说了,在两个函数出现同名的变量不会互相干扰,就是这个道理。所以上面的两个输出,在主函数里仍然是5,在add()函数里输出是6。 2.全局作用域 对于具有全局作用域的变量,我们可以在程序的任何位置访问它们。当一个变量是在所有函数的外部声明,也就是在程序的开头声明,那么这个变量就是全局变量。
void add(int); int num;
main() { int n=5; add(n); printf(%d\n,num); /*输出6*/ }
void add(num) /*形式参数没有指定类型*/ { num++; printf(%d\n,num); /*输出6*/ }
上面的main()和add()里面,并没有声明num,但是在最后输出的时候却要求输出num,这是由于在程序的开始声明了num是全局变量,也就是在所有函数里都可以使用这个变量。这时候一个函数里改变了变量的值,其他函数里的值也会出现影响。上面的例子输出都是6,因为在add()函数里改变了num的值,由于num是全局变量,就好象它们两个函数共用一个变量,所以在main()函数里的num也随之改变了。
3.文件作用域 在很多C语言书上,都没有说明文件作用域,或者只是略微的提到,其实文件作用域在较大程序中很有作用(在多文件系统中)。文件作用域是指外部标识符仅在声明它的同一个转换单元内的函数汇总可见。所谓转换单元是指定义这些变量和函数的源代码文件(包括任何通过#include指令包含的源代码文件)。static存储类型修饰符指定了变量具有文件作用域。
static int num; static void add(int);
main() { scanf(%d,&num); add(num) printf(%d\n,num); }
void add(num) { num++; } 上面的程序中变量num和函数add()在声明是采用了static存储类型修饰符,这使得它们具有文件作用域,仅爱定义它们的文件内可见。 由于我们提到的大多数程序都只有一个编译文件组成,所以这种写法没有实际意义。但是实际工程上的文件有很多,它们不是由一个人写成的,由很多人共同完成,这些文件都是各自编译的,这难免使得某些人使用了一样的全局变量名,那么为了以后程序中各自的变量和函数不互相干扰,就可以使用static修饰符,这样在连接到同一个程序的其他代码文件而言就是不可见的。
二、变量存储类型 前面我们说了,声明变量时用如下类似的形式: int num; float total; 它们都没有存储类型修饰符,我们在声明时也可以通过存储类型修饰符来告诉编译器将要处理什么类型的变量。存储类型有以下四种:自动(auto)、静态(static)、外部(extern)、寄存器(regiser)。 1.自动存储类型 自动存储类型修饰符指定了一个局部变量为自动的,这意味着,每次执行到定义该变量的语句块时,都将会为该变量在内存中产生一个新的拷贝,并对其进行初始化。实际上,如果不特别指明,局部变量的存储类型就默认为自动的,因此,加不加auto都可以。 main() { auto int num=5; printf(%d\n,num); } 在这个例子中,不论变量num的声明是否包含关键字auto,代码的执行效果都是一样的。函数的形式参数存储类型默认也是自动的。 2.静态存储变量 前面已经使用了static关键字,但是对于局部变量,静态存储类型的意义是不一样的,这时,它是和自动存储类型相对而言的。静态局部变量的作用域仍然近局限于声明它的语句块中,但是在语句块执行期间,变量将始终保持它的值。而且,初始化值只在语句块第一次执行是起作用。在随后的运行过程中,变量将保持语句块上一次执行时的值。看下面两个对应的程序:
/*1.C*/ /*2.C*/ int add(); int add();
main() main() { { int result; int result; result=add() result=add(); printf(%d ,result); printf(%d ,result); result=add(); result=add(); printf(%d ,result); printf(%d ,result); result=add(); result=add(); printf(%d,result); printf(%d,result); } }
int add() int add() { { int num=50; static int num=50; num++; num++; return num; return num; } }
上面两个源文件,只有函数add()里的变量声明有所不同,一个是自动存储类型,一个是静态存储类型。 对于1.C文件,输出结果为51 51 51;这很好理解,每次初始值都是50,然后加1上来。 对于2.C文件,输出结果为51 52 53;这是由于变量是静态的,只在第一次初始化了50,以后都是使用上次的结果值。当第一次调用add()时,初始化为50,然后加1,输出为51;当第二次调用时,就不初始化了,这时num的值为上次的51,然后加1,输出52;当第三次调用时,num为52,加1就是53了。 比较就会发现它们的不同之处了。静态变量在下一节要说的递归函数中经常使用到。 当第一次不指明静态变量的初始值时,默认为0。
[1] [2] 下一页
|
| 文章录入:admin 责任编辑:admin |
|
上一个文章: C语言函数参数的传递和值返回 下一个文章: 没有了 |
| 【字体:小 大】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 |