【C++ Primer Plus 9.2】 存储持续性、作用域和链接性

9.2 存储持续性、作用域和链接性(C++存储数据的方案)

了解:C++存储数据的方案;

9.2.1 存储持续性、作用域、链接不同的C++存储方式是通过存储持续性、作用域和链接性描述的。

1. 存储持续性 C++使用三种(C++11中是4种)不同的方案来存储数据(区别在于数据在内存中的时间) 自动存储持续性:函数中声明的变量;函数或代码块结束时释放内存。. 静态存储持续性:函数外定义或static声明的变量;整个程序运行过程中都存在。 线程存储持续性(C++11):thread_local声明 动态存储持续性:new分配。 2. 作用域 作用域描述了名称在文件中的可见范围。 3. 链接性 链接性描述名称如何在不同单元中共享。 外部链接性:可在文件间共享。 内部链接性:只能在一个文件中的函数共享。

9.2.2 自动变量默认情况下,函数中声明的参数和变量存储持续性为自动,作用域局部,没有链接性(只在函数中或代码块中使用)自动变量和栈 留出一块内存,将其视为栈;程序使用栈顶指针(指向下一个可用内存)和栈底指针来跟踪栈; 函数调用时,自动变量压栈;函数结束时,栈顶指针重置为调用前的值,从而释放了新变量使用的内存9.2.3 静态变量

与自动变量相比,静态变量寿命长,不需要使用栈来管理,编译器分配固定的内存来存储静态变量;静态变量在程序的整个执行过程中都存在。静态变量默认初始化为0;

;one_file=50; //静态变量,内部链接性;能在包含该代码段的文件中使用int main(){int a=10;}void fun(int n){llama=0; //自动变量}静态持续性、外部链接性(可在其他文件中使用) a. 因为外部变量可能在其他文件中使用,所以有了单定义规则(One Definition Rule):变量只能定义一次;C++提供了两种变量声明:一种是定义声明,,给变量分配内存空间;另一种是引用声明,不分配内存空间,只是引用已有的变量。 b. 程序说明;void add_a(int n);void local();int a = 100; //全局变量,外部链接性int main(){cout << a << endl;add_a(a);local();}::cout;a;void add_a(int a){a++;cout << a << ‘\n’;}void local(){int a = 2;cout << ::a << ‘\n’; //利用作用域解系符使用全局变量版本 }

2.静态持续性、内部链接性(只能在当前文件中使用)

//file1.cppint errors=5;errors=23; 正确,在该文件中,静态变量将隐藏外部变量void fun(){}

3.静态持续性、无链接性(只能在当前代码块或函数中使用) 在代码块中定义的static变量无链接性,特点是在改代码块不活动时仍然存在。

;void s(){count=0;//无论该函数被调用几次,这条语句只会被执行一次int _count=0;cout<<count<<” “<<_count<<endl;count++;}int main(){int i=10;while(i–)s();return 0;}运行后输出:

可以看出,如果初始化了静态局部变量,则程序只在启动时进行一次初始化;以后再调用函数时,将不会像自动变量那样再次被初始化,也就是说,static int count=0;只会被程序执行一次;

9.2.4 存储说明符和cv-限定符存储说明符: a. auto(C++11中不再是说明符,而是用于自动类型推断)、 b. register(C++11中用来显式地指出变量是自动的) c. static(作用域是整个文件时表示内部链接性、作用域是代码块时表示无链接性) d. extern(引用声明,声明在其他文件中引用全局变量) e. thread_local(C++11) f. mutable(表明即使结构(类)变量为const,其某个成员也可以被修改);struct data{char name[30];mutable int access;};const data veep = { “Chao Wen”, 0 };strcpy(veep.name, “John”); //不允许veep.access++;//允许/*const限定符禁止程序修改veep的成员,所以veep.name是不可修改的,但是access成员的mutable说明符使得access不受这种限制*/cv-限定符 a. const(表明内存被初始化后,就不能够被修改) const限定符对默认存储类型稍有影响。默认情况下全局变量的链接性为外部,但是const全局变量的链接性是内部的。 代码说明//test.h/*由于const的链接性是内部的,所以可以在所有的文件中使用同一组声明*/const int a = 12;Print();;void Print(){cout << &a << endl;};#include”test.h”int main(){Print();cout << &a << endl;}

输出: 0x47f004 0x47f000

可以看到,头文件中定义的const int a=12;在main.cpp和test.cpp中虽然值相同,但是内存地址并不同,说明两个文件中的a并不是同一个。 如果定义static int a=14;那么同样,两个文件中的a虽然值相同,但并不是同一个a,每个文件中a的链接性均为内部的,即只可以在该文件中使用。 而如果定义int a=13;那么编译器提示”multiple definition of ‘a’”,明显违反了单定义规则,因为全局变量的链接性必须是外部的,所有文件中必须共有一个a;这显然提示我们,非const的全局变量的声明不能够放在头文件中(而声明为const的全局变量链接性已经变为了内部); 总结一下,在头文件中:

a=a=1; //ok那绿叶上的水珠,是思念的泪滴。

【C++ Primer Plus 9.2】 存储持续性、作用域和链接性

相关文章:

你感兴趣的文章:

标签云: