static在内存层面的作用_「C++ Primer plus 心得」9.内存模型和名称空间
本章内容包括:
- 单独编译
- 存储持续性、作用域和链接性
- 定位new运算符
- 名称空间
C++ 为在内存中存储数据方面提供了多种选择。可以厅数据保留在内存中的时间长度(存储持续性)以及程序的哪一部分可以访问数据(作用域和链接)等,可以使用new来动态地分配内存,而定位new运算符提供了这种技术的一种变种。C++名称空间是另一种控制访问权的方式。通常,大小程序都由多个源代码文件组成,这些文件可能共享一些数据,这样的程序设计到程序文件的单独编译,首先我们就来一起看看单独编译的内容。
9.1 单独编译
C++ 允许鼓励将组件函数放在独立的文件中,可以单独编译这些文件,然后将他们链接成可执行程序;
例如有两个源代码文件:main.cpp, static.cpp
将两个源代码文件和新的头文件一起进行编译和链接,将生成一个可执行程序
程序文件:
- 头文件: 包含结构声明和使用这些结构的函数原型;
- 源代码文件: 包含与结构有关的函数的代码;(函数定义)
- 源代码文件: 包含调用与结构相关的函数代码(main 和其他使用这些函数的函数)
头文件管理:
在同一个文件中只能将同一个头文件包含一次,为避免多次包含同一个头文件:
使用基于预处理器编译指令 #ifndef (即 if not defined):
#ifndef COORDIN_H_. . .#endif
#define COORDIN_H_: 完成名称定义
头文件中常包含的内容:
- 函数原型
- 使用#define 或 const 定义的符号常量
- 结构声明
- 类声明
- 模板声明
- 内联函数
9.2 存储持续性、作用域和链接性
C++ 使用3种不同的方案来存储数据,区别在于数据保留在内存中的时间:
1. 自动存储持续性:
在函数定义中声明的变量(包括函数参数)的存储持续性为自动的;
在程序开始执行所属的函数代码块时被创建,在执行完函数或代码块时,被释放;
C++ 有两种存储持续性为自动的变量
2. 静态存储持续性:
在函数定义外定义的变量和使用的关键字 static 定义的变量的存储持续性都为静态;
静态变量在程序整个运行过程都存在;
C++有3种存储持续性为静态的变量
3. 动态存储持续性:
用 new 操作符分配的内存将一直存在,知道使用 delete 操作符将其释放或程序结束为止;
这种内存的存储持续性为动态,有时又称自由存储
9.2.1 作用域和链接
作用域描述了名称在文件的多大范围内可见;
链接性描述了名称如何在不同单元间共享;
9.2.2 自动存储持续性
默认情况下,在函数中声明的函数参数和变量的存储持续性为自动,作用域为局部,没有链接性;
函数开始执行变量所属的代码块时,将为其分配内存,当函数结束时,变量消失(作用域起点为声明的位置);
可以使用C++(和C)关键字 auto 来显示地指出存储类别:
由于关键字 auto 用于默认状态下为自动的变量,因此程序员几乎不使用它
可以使用任何在声明时其值为已知的表达式来初始化自动变量;
自动变量的管理采用堆栈,自动变量的数目随函数的开始和结束而增减(后进先出);
C++也支持使用 register 关键字来声明局部变量,寄存器变量是另一种形式的自动变量:
CPU 访问寄存器中的值的速度比访问堆栈中内存快;
声明寄存器变量:register int count_fast // request for a register variable
一般 register 变量说明符指出变量将被频繁的使用
9.2.3 静态持续变量
C++ 也为静态存储持续性变量提供了 3 种链接性:外部链接性、内部链接性和无链接性;
静态变量在整个程序执行期间一直存在;
如果没有显示的初始化静态变量,编译器将它设置为 0;
要创建链接性为外部的静态持续变量,必须在代码块的外面声明它;
要创建链接性为内部的静态持续变量,必须在代码块的外面声明它,并使用 static 限定符;
要创建没有链接性的静态持续变量,必须在代码块内声明它,并使用 static 限定符
1. 静态持续性、外部链接性
double warming = 0.3; // 定义声明,给变量分配存储空间,并初始化extren double warming; // 引用声明,不给变量分配存储空间,引用已有变量,声明指出使用外部定义的变量 warming
定义与全局变量同名的局部变量后,局部变量将隐藏全局变量;
C++ 提供了作用域解析操作符(::),当放在变量名称前面时,操作符表示使用变量的全局版本(:: warming)
2. 静态持续性、内部链接性
将 static 限定符用于作用域为整个文件的变量时,该变量的链接性是为内部的;
链接性为内部的变量只能在其所属的文件中使用;
对于外部链接性变量,有且只有一个文件包含了该变量的外部定义,其他文件使用该变量,必须在引用声明中使用关键字 extern;
应使用外部变量在多文件程序的不同部分之间共享数据;
应使用链接性为内部的静态变量在同一个文件中的多个函数之间共享(名称空间提供了另外一种共享数据的方法)
3. 静态存储持续性、无链接性
将 static 限定符用于在代码块中定义的变量,将导致局部变量的存储持续性为静态的;
该变量只在改代码块中可用,但它在该代码块不处于活动状态时任然存在:
两次函数调用之间,静态变量的值将保持不变;
如果初始化了静态局部变量,程序只在启动时进行一次初始化(初始化一次)
9.2.4 说明符和限定符
存储说明符:
- auto 自动变量
- 2. register 寄存器存储类型
- static 被用在整个文件的声明中,表示内部链接性;被用于局部声明中,表示局部变量的存储类型为静态的
- extern 引用声明,声明引用在其他地方定义的变量
- mutable 当结构变量为 const ,用 mutable 说明的成员也可以被修改
再谈 const:
const 全局变量的链接性为内部的:
const int fingers = 10 // same as static const int fingers
可以把常量放在头文件中,同一工程下的多个文件使用该头文件后,可以得到常量定义
9.2.5 函数链接性
所有函数的存储持续性都自动为静态的,即在整个程序执行期间都一直存在;
默认情况下,函数链接性为外部的,可以在文件间共享;
可以使用 static 将函数链接性设置为内部的,使之只能在一个文件中使用;
C++ 在哪里查找函数:
如果函数原型指出函数是静态的,则编译器只在文件中查找函数定义;
否则,编译器将在所有文件中查找
9.3 名称空间
C++ 提供了名称空间工具,以便更好地控制名称的作用域:
namespace Tack { double pail; void fetch ( ); int pal; struct Well { . . . };}
除了用户定义的名称空间外,还存在另一个名称空间——全局名称空间,对应于文件级声明区域(全局变量);
名称空间是开放的(open):
可以把名称加入到已有名称空间中;
可以在文件后面再次引用 Tack 名称空间来提供函数代码:
namespace Tack { void fetch () { . . . }}
包含名称空间的名称(如 Tack :: pail)被称为限定的名称;
using 声明和 using 编译指令
using 声明使特定的标识符可用:using std :: cout;
在函数内部声明将名称添加到局部声明区域;
在函数外面声明将名称添加到全局名称空间中
using 编译指令使整个名称空间可用:
using namespace std;使得所有名称空间的名称全局可用
名称空间可以进行嵌套;
未命名的名称空间相当于链接性为内部的静态变量(C++不赞成在名称空间和全局作用域中使用关键字 static)
9.3.4 名称空间及其前途
- 使用已命名的名称空间中声明的变量,而不是使用外部全局变量;
- 使用已命名的名称空间中声明的变量,而不是使用静态全局变量;
- 如果开发了一个函数库或者类库,将其放在一个名称空间中;
- 不要在函数头使用 using 编译指令;
- 导入名称时首先使用作用域解析操作符或 using 声明的方法;
static在内存层面的作用_「C++ Primer plus 心得」9.内存模型和名称空间相关推荐
- 基类的构造函数也可以被继承_「C++ Primer plus 心得」13.类继承
本章内容: is-a 关系的继承: 如何以公有方式从一个类派生出另一个类: 保护访问: 构造函数成员初始化列表: 向上和向下强制转换: 虚成员函数: 早期(静态)联编与晚期(动态)联编: 抽象基类: ...
- define定义的函数如何引用_「C与指针心得」25.预处理器-宏函数
感谢您的阅读与点赞!欢迎关注:「大猫玩程序」,查看C语言系列文章 上一节讲了一些系统的预定义宏,这一节来讲一讲 宏定义.宏函数. 预处理常量 define: 预处理器指令从#开始,到最后第一个换行符为 ...
- static在内存层面的作用_虚拟地址空间--用户进程看到的自己所占用的内存
我们知道内核管理物理内存,其实除了管理本身内存外,还必须管理用户空间中进程的内存,我们称这个内存为进程地址空间,也就是系统中每个用户空间进程所看到的内存. 传统的C语言编译出来的进程地址空间包含哪些对 ...
- 2020 我的C++的学习之路 第九章 内存模型与名称空间
以C++ Primer Plus为参考书籍,自身归纳知识点,加深记忆. 内存模型与名称空间 存储持续性 作用域与链接 自动存储持续性 静态持续变量 静态持续性.外部链接性 静态持续性.内部链接性 静态 ...
- 《C++ Primer Plus》读书笔记之七—内存模型和名称空间
第九章 内存模型和名称空间 1.不要将函数定义或者变量声明放到头文件中. 2.头文件常包含的内容:函数原型.使用#define或者const定义的常量.结构声明.类声明.模板声明.内联函数. 3.避免 ...
- C++ Primer Plus学习(九)——内存模型和名称空间
内存模型和名称空间 单独编译 存储持续性.作用域和链接性 名称空间 单独编译 程序一般可以分为三部分: 头文件:包含结构声明和使用这些结构的函数的原型: 源代码文件:包含与结构有关的函数的代码: 源代 ...
- static在内存层面的作用_static的作用和内存划分?
有时希望函数中的局部变量的值在函数调用结束后不消失而继续保留原值,即其占用的存储单元不释放,在下一次再调用的时候该变量已经有值.这时就应该指定该局部变量为静态变量,用关键字 static 进行声明. ...
- 热成像成像不清楚是什么时候_「从零搞机」热成像仪查看 分形工艺Node 202 机箱 风道散热情况...
分形工艺的Node 202是我非常喜欢的一个机箱,是现如今搞机圈一众肥宅A4机箱里为数不多的瘦高个. 分形工艺Fractal Design Node 202 为什么喜欢它? 好看,耐看 分形工艺的设计 ...
- 扩展中断控制器8259实验_「正点原子FPGA连载」第十三章双核AMP实验
1)摘自[正点原子]领航者 ZYNQ 之嵌入式开发指南 2)实验平台:正点原子领航者ZYNQ开发板 3)平台购买地址:https://item.taobao.com/item.htm?&id= ...
最新文章
- java什么时会出现gc_面试题:java GC发生在会么时候,对什么东西,做了什么事情...
- mysql用if判断关联的表_mysql表连接,子查询以及if判断
- 如何把模型表导入数据库
- matlab中循环读入文件内容,[转载]Matlab利用load循环读入数据文件
- 客户端无法连接到远程计算机。可能没有启用远程连接
- 帮内推 | 免费送50个推荐算法工程师的高薪offer!
- 智能优化算法(源码)-生物地理学算法(Biogeography-Based Optimization,BBO)
- 中国移动MM如何助力网络视频反盗版
- 【AI视野·今日CV 计算机视觉论文速览 第167期】Mon, 11 Nov 2019
- 【搞一点AUTOSAR】基于TC397的MACL_ADC配置(Davinci工具链)
- 使用hibernate的@SQLDelete和@Where注解实现逻辑删除
- Java面试常考之 单例设计模式(饿汉式单例、 懒汉式单例)
- 一位期货人的总结:大道至简,悟者大成
- 科学计算机怎么锁死,人类的技术科学被“锁死”,科学家已证实,仍有很多人不相信!...
- C语言:输出1~1000 之间所有的完全平方数
- 裴蜀定理(贝祖定理) 证明与应用
- win10设置开机启动项_华硕主板如何设置开机第一启动项方法大全
- 将人像照做成旋转风车效果!超实用Photoshop教程
- 【C语言】请将560分钟换算成几小时几分钟,并输出换算结果相应的小时数与分钟数。 个人题解
- Kubernetes(四) - Pod和Deployment
热门文章
- ubuntu系统debootstrap的使用
- 迭代器报“vector iterators incompatible”错的几种可能
- Linux2.6内核 -- 编码风格(2)
- linux下查看和添加PATH环境变量
- Linux内存管理之高端内存映射
- openEuler系统配置yum镜像源
- mysql默认几个库_MySQL 安装初始化mysql后,默认几个库介绍
- html 点击一行变色,elementui点击table每一行会变色,当有固定列的时候,
- java dom 解析xml 例子,Java DOM解析XML的幾個例子
- 9非标功能包_非标设备问题预防和解决的常用方法