作用域、链接属性、存储类型示例——文件之间变量、函数的关系
2014-03-20 15:57
411 查看
这两天在看《C和指针》书的时候,总结了一下文件中变量和函数的作用域、链接属性,变量还有各种存储类型。
当变量在程序的某个部分被声明时,它只有在程序的一定区域才能被访问。这个区域由标识符的作用域(scope)决定。
编译器可以确认4种类型的作用域——文件作用域、代码作用域、原型作用域和函数作用域。(这里没有提到函数作用域,它只适用于语句标签,语句标签用于goto语句。)
链接属性一共有3种——extrenal(外部)、internal(内部)和none(无)。none链接属性如:函数的参数,代码块作用域的变量,标签等。标识符的作用域与它的连接属性有关,但这两个属性并不相同。
变量的存储类型(storage class)是指存储变量值的内存类型。变量的存储类型决定变量何时创建、何时销毁以及它的值将保持多久。有三个地方可以用于存储变量:普通内存、运行时堆栈、硬件寄存器。
代码块外声明的变量:存储在静态内存中,属于静态(static)变量。
代码块内声明的变量:存储在堆栈中,缺省为自动(auto)变量。
最后,关键字register可以用于自动变量的声明,提示它们应该存储于机器的硬件寄存器而不是内存中,这类变量称为寄存器变量。注意:如果有太多的变量被声明为register,只选取前几个实际存储于寄存器中,其余的就按自动变量处理。
下面有一个自己写的测试代码,不知道有没有讲清楚,但是希望对别人有帮助。
file2.cpp 文件2源文件
从示例程序我们可以发现几点:
初始化:如果不显式指定静态变量的初始值,它将初始化为0;自动变量则是个随机值。
static关键字:当用于函数定义时,或用于代码块之外的变量声明时,static关键字用于修改标识符的连接属性,从external变为internal(变量g,h),但是标识符的存储类型和作用域不受影响。当用于代码块内部变量的声明时,static关键字用于修改变量的存储类型,从自动变量修改为静态变量,但是变量的作用域和连接属性不受影响。
对于函数而言,存储类型并不是问题,因为代码总是存储于静态内存中。
当变量在程序的某个部分被声明时,它只有在程序的一定区域才能被访问。这个区域由标识符的作用域(scope)决定。
编译器可以确认4种类型的作用域——文件作用域、代码作用域、原型作用域和函数作用域。(这里没有提到函数作用域,它只适用于语句标签,语句标签用于goto语句。)
链接属性一共有3种——extrenal(外部)、internal(内部)和none(无)。none链接属性如:函数的参数,代码块作用域的变量,标签等。标识符的作用域与它的连接属性有关,但这两个属性并不相同。
变量的存储类型(storage class)是指存储变量值的内存类型。变量的存储类型决定变量何时创建、何时销毁以及它的值将保持多久。有三个地方可以用于存储变量:普通内存、运行时堆栈、硬件寄存器。
代码块外声明的变量:存储在静态内存中,属于静态(static)变量。
代码块内声明的变量:存储在堆栈中,缺省为自动(auto)变量。
最后,关键字register可以用于自动变量的声明,提示它们应该存储于机器的硬件寄存器而不是内存中,这类变量称为寄存器变量。注意:如果有太多的变量被声明为register,只选取前几个实际存储于寄存器中,其余的就按自动变量处理。
下面有一个自己写的测试代码,不知道有没有讲清楚,但是希望对别人有帮助。
file2.cpp 文件2源文件
/*文件2*/ #include <stdio.h> //函数f2_fun1:文件作用域,external链接属性(缺省) void f2_fun1(); //变量j,k:文件作用域,external链接属性(缺省),static存储类型(缺省) int j = 1; int k; //外部链接文件1中的变量a和函数f1_fun2 extern int a; extern void f1_fun2(void); void f2_fun1() { int b = a; printf("文件1调用文件2外部链接函数:f2_fun1!b = %d\n", b); f1_fun2(); }file1.cpp文件1源文件
/*文件1*/ #include <stdio.h> //变量a:文件作用域,external链接属性(缺省),static存储类型 int a = 1; //变量b:文件作用域,internal链接属性,static存储类型 static int b; //函数f1_fun1:文件作用域,internal链接属性 //形参v:原型作用域,none链接属性,auto存储类型 static void f1_fun1(int v); //函数f1_fun2:文件作用域,external链接属性(缺省) void f1_fun2(void); int main() { printf("文件1变量:a = %d,b = %d\n", a, b); //变量e和f:代码作用域,none链接属性,register存储类型 register int c = 1, d; printf("文件1变量:c = %d\n", c); //变量g和h:代码作用域,none链接属性,auto存储类型(缺省) int e = 1, f; printf("文件1变量:e = %d\n", e); //变量i和j:代码作用域,none链接属性,static存储类型 static int g = 1, h; printf("文件1变量:g = %d,h = %d\n", g, h); //一个代码作用域 { //变量g:代码作用域,none链接属性,auto存储类型(缺省) int g = 2; printf("文件1变量:g = %d\n", g);//内层标示符g将隐藏外层标示符g。 } //另一个代码作用域 { //函数f3:代码块作用域,external链接属性(缺省) void f2_fun1(); //变量j,k:代码块作用域,extrenal链接属性,根据被调用文件类型 extern int j; extern int k; printf("文件1调用文件2外部链接变量:j = %d,k = %d\n", j, k); f2_fun1(); } f1_fun1(1); return 0; } void f1_fun1(int v) { printf("文件1函数:f1_fun1!v = %d\n", v); } void f1_fun2(void) { printf("文件2外部链接文件1函数:f1_fun2!\n"); }下面是附上两张图片,一张是测试结果图,另一张是调试结果图,主要是为了看没有初始化的变量d,f,h的值,因为VS2012显示未初始化的变量报错,所以通过调试来观察它们的结果。
从示例程序我们可以发现几点:
初始化:如果不显式指定静态变量的初始值,它将初始化为0;自动变量则是个随机值。
static关键字:当用于函数定义时,或用于代码块之外的变量声明时,static关键字用于修改标识符的连接属性,从external变为internal(变量g,h),但是标识符的存储类型和作用域不受影响。当用于代码块内部变量的声明时,static关键字用于修改变量的存储类型,从自动变量修改为静态变量,但是变量的作用域和连接属性不受影响。
对于函数而言,存储类型并不是问题,因为代码总是存储于静态内存中。
相关文章推荐
- 作用域、全局局部变量、链接属性、存储属性、生存期、内部外部函数
- 作用域 属性链接 存储类型
- 作用域、链接属性和存储类型的总结
- 作用域、链接属性、存储类型总结
- 变量的作用域、链接属性和存储类型
- 变量及函数的生存期、作用范围、链接属性
- C作用域、链接属性、存储类型和初始化
- 【转】作用域、链接属性、存储类型总结--转载学习,很清晰,很详细
- IoCreateSymbolicLink函数的作用以及符号链接、设备名称之间的关系
- 变量和函数的作用域、链接属性、存储范围
- C语言之作用域 链接属性 存储时期 存储类型
- 嵌入式 Linux C语言(八)——存储类型、作用域、生命周期、链接属性
- 作用域+链接属性+存储类型
- 作用域+链接属性+存储类型
- 嵌入式 Linux C语言(八)——存储类型、作用域、生命周期、链接属性
- 作用域、链接属性和存储类型
- C学习笔记:变量作用域、链接属性、存储类型
- [Linux文件属性]使用symlink函数建立符号链接文件
- const、&在定义函数返回的作用及接收返回变量的类型
- 变量存储类型、作用域