C++ Primer Plus 随记(第九章)内存模型和名称空间

1、单独编译

头文件:包含结构声明和使用这些结构的函数的原型

源文件:包含与结构实现有关的函数的代码;

源文件:包含调用与结构相关的函数的代码。

一般的程序组织结构如上所示分为三个部分,这种形式避免了 结构 的修改不影响其基本调用,编译也不需要全部重新编译。

同一个文件只能将同一个头文件包含一次,下属代码避免了这种问题。

#ifndef ***_H_     #define ***_H_      ...       #endif                // 防止上述问题

2、存储持续性、作用域和链接性

自动存储持续性:函数定义中声明的变量。  执行时创建,执行结束时释放                                                 无链接性(仅可在当前函数/代码块中访问)

静态存储持续性: static 关键词声明和函数定义外定义的变量。   整个运行期都存在                                   外部链接性(可在其它文件访问)、内部链接性(仅当前文件)、无链接性       

线程存储持续性(C++11):关键词thread_local 声明。    生命周期与线程一样长                                                  

动态存储持续性:new运算符分配。        delete运算符释放或者程序结束   (自由存储/堆)           

3、变量存储方式

存储描述持续性作用域链接性如何声明
自动自动代码块代码块中
存储器自动代码块代码块中,使用 register 关键字
静态、无链接静态代码块代码块中,使用 static 关键字
静态、外部链接性静态文件外部不在任何函数内
静态、内部链接性静态文件内部不在任何函数内,使用关键字 static

3、自动存储持续性

函数声明中的参数和函数内部变量       局部作用域     没有链接性

自动变量的数目随着程序的开始和结束而增减    在程序中单独开辟的 栈 中进行操作   栈的顺序为后进先出

关键词 register 显示指示该变量为自动变量。

4、静态持续变量 

不同的声明方式决定了变量的链接性①、外部链接性 --  必须在代码块的外面声明;②、内部链接性 -- 必须在代码块的外部使用 static 关键字声明;③、无连接性 -- 在代码块内部使用 static 关键字声明。

静态变量在固定的内存中  存在于整个程序的执行期间。    若未使用 常量 进行显示初始化,将自动被初始化为 0 。

5、使用 extern 关键字将其他文件的静态外部链接性变量引用到 当前文件,但是该变量不可以进行初始化,初始化导致变量定义的行为。

注意:同名的局部变量可以隐藏全局变量        作用域解析运算符(::)可以在此情况下仍使用全局变量。

全局变量的缺点:由于对数据访问的任意性,可能会导致程序不可靠;优点:多个函数使用同一个数据块(不需要进行参数的传递)。

6、静态变量该程序段结束(离开作用域),也会继续存在与内存中(位置是固定的,在程序结束后内存才会被回收)。

再次运行到该程序段,不会再次初始化(只会初始化一次)

7、存储说明符:

thread_local、auto、register、static、extern、mutable。 

上述说明符 除了 thread_local 可以和 static或extern 配合使用外,其他的说明符只可以单独使用。

thread_local:线程存储周期;register:寄存器变量;static:静态变量声明;

mutable:修饰结构变量或类变量的成员时,即使声明为 const ,也可以修改该变量。

8、cv-限定符

const:内存初始化后不再被修改;

volatile:即使程序没有修改内存,其值也可能被修改(硬件修改)。此限定符表示每次读取该变量的实际存储位置,而非读取内存中的变量副本。

9、const 结合 extern

const int finger;   // 变量定义为内部链接性

extern const int finger;   // 不可以进行初始化   

上述代码和 extern int fingers; // 一样不可以初始化

但是其在每个文件中存在着各自的一组变量,并不是共享同一组变量。

extern const int fingers = 5; // 变量定义并为外部链接性,并覆盖了原有的变量

此种定义确保各文件之间为共享同一组变量。

10、函数和链接性

函数的存储连续性全部为静态(函数内不可以定义函数 ),链接性为外部(可以在文件之间共享)

可以使用 extern 明确指示该函数在其他文件中定义,也可以使用 static 限定函数仅可以在该文件内使用(其他文件中可以有同名文件)。

函数调用顺序:

11、语言链接性

由于语言的标准不同,C/C++语言的编译器针对函数名的翻译不一样。

可以使用查询约定使用的函数原型

extern “C” void spiff(int);      // 使用 C 语言链接性 用于名称查找

extern  void spiff(int);           // 使用 C++ 语言链接性 用于名称查找

extern “C++” void spiff(int);  // 使用 C++ 语言链接性 用于名称查找

12、动态分配:new、delete 运算符

动态内存分配: new运算符申请,delete运算符销毁变量

int *pi = new int (6);     //  申请并初始化 int 型变量

int *pin = new  int [4]{2,4,6,8};     // 申请整形数组并初始化        还可以用 {} 初始化结构、初始化单值

new函数申请内存失败:返回空指针、现在将会引发异常  std::bad_alloc。

new、delete 运算符可以针对性的进行重载。

13、定位运算符 new

char buf[50];

chaf *p2 = new (buf) chaf;     // chaf 为自定义结构体   新申请的 chaf 变量位于内存中的 buf 内   

上述的 p2 不可以使用 delete 运算符释放(buf的内存为静态内存,在delete运算符的适用范围之外)

new 可以接受两个参数

int *pi = new int ;                             // new(sizeof(int)) 

chaf *p2 = new (buf) chaf[40];         // new(40*sizeof(chaf),buf)

14、名称空间

声明区域:可以在其中进行声明的区域(代码块、整个文件)

潜在作用域:变量的潜在作用域从声明位置到声明区域结束;

变量在潜在作用域内可以被其他变量隐藏。

名称空间:通过定义一种新的声明区域来创建命名的名称空间,可以提供一个声明名称的区域,不同名称空间之间的相同名称不会冲突。

15、命名空间使用方式        -----         命名空间::变量名;

using 命名空间;    //  using 编译指令      导入命名空间中的全部名称                          ---      可能会导致命名空间中的变量覆盖 程序中的其他变量

using  命名空间::变量名;      //  using 声明       使用命名空间中的某变量,后续直接使用该变量

命名空间可以嵌套

未命名的名称空间表示:其中的名称从声明位置到该声明区域末尾都可以使用

 

              

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值