auto
对应自动生存周期
声明中有auto修饰符的对象具有自动生存周期。
它们仅存在于被定义的当前执行代码块中,即局部变量在进入模块时生成,在退出模块时消亡。
定义局部变量的最常见的代码块是函数。 语言中包括了关键字auto,它可用于定义局部变量。但自从所有的非全局变量的缺省值假定为auto以来,auto就几乎很少使用了。
如果是定义在函数外,那么该对象具有内部链接,其它程序文件不能对其访问。如果是定义在函数内,那么该对象具有无链接,函数外不能对其访问。
(注意:static变量初始化时,只能用常量)
用 static 关键字修饰的局部变量称为静态局部变量。
静态局部变量存值如同全局变量,区别在于它只属于拥有它的函数,它也和全局变量一样会被初始化为空。
在C++环境下使用C函数的时候,常常会出现编译器无法找到obj模块中的C函数定义,从而导致链接失败的情况,应该如何解决这种情况呢? 答案与分析: C++语言在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称,而C语言则不会,因此会造成链接时找不到对应函数的情况,此时C函数就需要用extern “C”进行链接指定,这告诉编译器,请保持我的名称,不要给我生成用于链接的中间函数名。 下面是一个标准的写法: //在.h文件的头上 #ifdef __cplusplus #if __cplusplus extern "C"{ #endif #endif /* __cplusplus */ … … //.h文件结束的地方 #ifdef __cplusplus #if __cplusplus } #endif #endif /* __cplusplus */
register修饰符暗示编译程序相应的变量将被频繁地使用,如果可能的话,应将其保存在CPU的寄存器中(而不是栈或堆),以加快其存储速度。然而,编译器不见得会这么做,因此效果一般般。了解一下就行,不建议使用。
volatile
一、局部变量和全局变量:
(1)局部变量:局部变量也叫自动变量,它声明在函数开始,生存于栈,它的生命随着函数的返回而结束。
- #include <stdio.h>
- int main(void)
- {
- auto int i = 9; <span style="white-space:pre"> </span>//声明局部变量的关键字是 auto; 因可以省略,所以几乎没人使用
- printf("%d\n", i);
- getchar();
- return 0;
- }
(2)全局变量:全局变量声明在函数体外,一般应在函数前。每个函数都可以使用它,不过全局变量应尽量少用。
- #include <stdio.h>
- void add(void);
- void mul(void);
- int gi = 3; <span style="white-space:pre"> </span>//全局变量(声明在函数外)
- int main(void)
- {
- printf("%d\n", gi); //输出的是 3
- add();
- printf("%d\n", gi); //输出的是 5
- mul();
- printf("%d\n", gi); //输出的是 10
- getchar();
- return 0;
- }
- void add(void) {
- gi += 2;
- }
- void mul(void) {
- gi *= 2;
- }
全局变量会被初始化为空, 而局部变量在没有赋值前是一个垃圾值:
- #include <stdio.h>
- int gi;<span style="white-space:pre"> </span>//全局变量
- int main(void)
- {
- int i;<span style="white-space:pre"> </span>//局部变量
- printf("%d, %d\n", gi, i);
- getchar();
- return 0;
- }
当全局变量与局部变量重名时,使用的是局部变量:
- #include <stdio.h>
- int a = 111, b = 222;
- int main(void)
- {
- int a = 123;
- printf("%d,%d\n", a, b);<span style="white-space:pre"> </span>//输出的是 123,222
- getchar();
- return 0;
- }
二、对象的生存周期(lifetime)
(1)静态生存周期(即全局变量的生存周期)
具有静态生存周期的所有对象,都是在程序开始执行之前就被事先创建和初始化。它们的寿命覆盖整个程序的执行过程。如在函数内定义了一个static变量,那第一次调用该函数后,该变量的值将会被保留,当第二次被调用时,该变量的值还是第一次调用结束时的值。
(2)自动生存周期(即局部变量的生存周期)
自动生存周期的对象的寿命由“对象定义所处在的大括号{}”决定。每次程序执行流进入一个语句块,此语句块自动生存周期的对象就会被创建一个新实例,同时被初始化。
三、标识符的链接(linkage)
(1)外部链接
表示在整个程序中(多个程序文件)是相同的函数或对象。常见的有,在函数体外声明的extern变量。
(2)内部链接
表示只在当前程序文件中是相同的函数或对象。其它程序文件不能对其进行访问。常见的有,在函数体外声明的static变量。
(3)无链接
一般声明在函数内部的auto、register变量、还有函数的参数,都是无链接。它的作用域是函数内部。
四、存储类型修饰符总结:
存储类型修饰符可以修改标识符的链接和对应对象的生存周期;标识符有链接,而非生命周期;对象有生存周期,而非链接;函数标识符只可用static、extern修饰,函数参数只可用register修饰。
(1)auto(对应自动生存周期)
auto修饰符只能用在函数内的对象声明中,即仅在语句块内使用。
声明中有auto修饰符的对象具有自动生存周期。
它们仅存在于被定义的当前执行代码块中,即局部变量在进入模块时生成,在退出模块时消亡。
定义局部变量的最常见的代码块是函数。 语言中包括了关键字auto,它可用于定义局部变量。但自从所有的非全局变量的缺省值假定为auto以来,auto就几乎很少使用了。
(2)static(对应静态生存周期)
如果是定义在函数外,那么该对象具有内部链接,其它程序文件不能对其访问。如果是定义在函数内,那么该对象具有无链接,函数外不能对其访问。
(注意:static变量初始化时,只能用常量)
用 static 关键字修饰的局部变量称为静态局部变量。
静态局部变量存值如同全局变量,区别在于它只属于拥有它的函数,它也和全局变量一样会被初始化为空。
- #include <stdio.h>
- void fun1(void);