【C++】C 语言 和 C++ 语言中 const 关键字分析 ② ( const 常量分配内存时机 | const 常量在编译阶段分配内存 )

2023-08-21 20:22:53





一、const 常量内存分配时机



在上一篇博客中 , 讲到了获取 const 常量的地址 , 代码如下 :

    // 定义常量
    // 该常量定义在了 符号表 中
    // 符号表 不在内存四区中 , 是另外一种机制
    const int a = 10;

    // 定义一个指针
    int* p = NULL;
    // 将 常量 a 的地址赋值给指针
    // 在 堆内存中重新 分配一个 4 字节的空间 
    // 将 常量 a 的值 10 存储进去
    p = (int *)&a;

在所有的编程语言中 , 常量 都具有如下特点 : 定义时分配内存 , 运行期间保持不变 ;

const 常量 通常指的是在程序运行期间其值不会改变的变量 , 常量在定义后会被分配内存 , 这个过程一般发生在编译器的编译阶段 ;

C++ 程序都是先进行编译 , 然后再执行 , 编译时分配内存意味着在程序运行之前 , 常量在程序内存中的位置就已经固定了 ;

const 常量值在 内存分配完毕后 就不能再被修改 , 因此可以使用常量表示固定值 , 如 : 圆周率 π \pi π , 自然数 e e e ;


const 常量 分配内存的时机 是 编译器 编译期间 进行分配的 ;

指针 p 获取 const 变量地址时 , 会在堆内存中为该指针分配一个内存地址 , 该分配内存的时机 是 编译器 编译 代码期间 进行的 ; ( 不是在运行期间分配内存的 )





二、使用如下代码验证 const 常量内存分配时机



使用如下代码验证 :

// 包含 C++ 头文件
//#include "iostream"

// 使用 std 标准命名空间
//		该命名空间中 , 定义了很多标准定义
//using namespace std;

#include <stdio.h>

int main()
{
    // 定义普通变量
    int a = 0;

    // 定义常量
    // 该常量定义在了 符号表 中
    // 符号表 不在内存四区中 , 是另外一种机制
    const int b = 10;

    // 定义普通变量
    int c = 0;
	
    // 打印上述三个常量/变量 的 地址
    printf("&a = %p , &b = %p , &c = %p\n", &a, &b, &c);

	// 控制台暂停 , 按任意键继续向后执行
	//system("pause");
    return 0;
}

执行结果 :

&a = 00B3F894 , &b = 00B3F888 , &c = 00B3F87C

D:\002_Project\006_Visual_Studio\HelloWorld\HelloWorld\Debug\HelloWorld.exe (进程 21584)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

在这里插入图片描述





三、分析验证结果 - const 常量在编译阶段分配内存



在上述代码中 , 先定义了变量 a , 再定义了常量 b , 最后定义了变量 c ;

变量 a 和 变量 c 肯定是在编译器编译时分配内存的 , 编译器扫描到了变量定义 , 为其分配内存 ;

这里尝试打印 常量 b 的地址 , 执行结果是

&a = 00B3F894 , &b = 00B3F888 , &c = 00B3F87C

三者之间 , 各差 12 字节的内存 , 三个 变量 / 常量 的内存是连续的 , 说明是在同一时间分配的内存 ;

变量 a 和 c 是编译器编译时分配的内存 , 三者内存连续 , 分配内存时间相同 , 说明 常量 b 也是在 编译器编译阶段 分配的内存 ;


这里注意 , 在 Visual Studio 2019 开发环境中 , int 类型本来占 4 字节 , 但是在 Debug 调试模式下 , 前后各分配了 4 字节用于存储调试信息 , 这样占了 12 字节 ;

更多推荐

Windows平台Qt6中UTF8与GBK文本编码互相转换、理解文本编码本质

快速答案UTF8转GBKQStringutf8_str="中UTF文";std::stringgbk_str(utf8_str.toLocal8Bit().data());GBK转UTF8std::stringgbk_str_given_by_somewhere="中GBK文";QStringutf8_str=QStr

GMAC & PHY介绍

1.1PHY接口发展(1)MII支持10M/100Mbps,一个接口由14根线组成,它的支持还是比较灵活的,但是有一个缺点是因为它一个端口用的信号线太多。参考芯片:DP83848、DM900A(该芯片内部集成了MAC和PHY接口)。DP83848芯片只支持10、100兆网络通信速度,采用4/5B编码。(2)RMII是简

机器学习第九课--随机森林

一.什么是集成模型对于几乎所有的分类问题(图像识别除外,因为对于图像识别问题,目前深度学习是标配),集成模型很多时候是我们的首选。比如构建一个评分卡系统,业界的标配是GBDT或者XGBoost等集成模型,主要因为它的效果确实好,而且稳定。还有一点是这些模型的可解释性也很好,不像深度学习模型就像个黑盒子。那为什么集成模型

ChatGpt介绍和国产ChatGpt对比

1.ChatGPT是美国OpenAI研发的聊天机器人程序,2022年11月30日发布。ChatGPT是人工智能技术驱动的自然语言处理工具,它能够通过理解和学习人类的语言来进行对话。2.ChatGPT是一种基于自然语言处理的聊天机器人程序。它使用深度学习技术,通过对大量语料库的学习和训练,可以生成类似人类语言的回复。Ch

java版工程管理系统Spring Cloud+Spring Boot+Mybatis实现工程管理系统源码

工程项目管理软件(工程项目管理系统)对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营,全过程、全方位的对项目进行综合管理工程项目各模块及其功能点清单一、系统管理1、数据字典:实现对数据字典标签的增删改查操作2、编码管理:实现对系统编码的增删改查操作3、用户管理:管理和查看用户角

《数字图像处理-OpenCV/Python》连载(2)目录

《数字图像处理-OpenCV/Python》连载(2)目录本书京东优惠购书链接:https://item.jd.com/14098452.html本书CSDN独家连载专栏:https://blog.csdn.net/youcans/category_12418787.html第一部分OpenCV-Python的基本操作

opencv滤波技术

文章目录前言一、均值滤波二、中值滤波三、高斯滤波四、双边滤波五、自适应滤波六、滤波器大小总结前言在OpenCV中,有多种滤波技术可以用于图像处理和图像增强。下面我将介绍五种常见的滤波技术,包括均值滤波、中值滤波、高斯滤波、双边滤波和自适应滤波,并提供相应的函数和使用方法。一、均值滤波均值滤波(MeanFiltering

rust迭代器

迭代器用来遍历容器。迭代器就是把容器中的所有元素按照顺序一个接一个的传递给处理逻辑。Rust中的迭代器标准库中定义了Iterator特性traitIterator{typeItem;fnnext(&mutself)->Option<Self::Item>;}实现了Iterator特性的结构体就是迭代器。很多类型都有it

线程、进程和管程

一、线程1.1定义线程:线程是进程中的实体,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程有时被称为轻量级进程,是程序执行流的最小单元。线程的组成部分:1.线程ID:线程标识符2.当前指令指针(PC)3.寄存器集合:存储单元寄存器的集合4.堆栈:堆栈是两种数据结构。堆栈都是一种数据项按序排列的数据结构,只能在

【Linux】自动化构建工具-make/Makefile详解

前言大家好吖,欢迎来到YY滴Linux系列,热烈欢迎!本章主要内容面向接触过Linux的老铁,主要内容含欢迎订阅YY滴Linux专栏!更多干货持续更新!以下是传送门!订阅专栏阅读:YY的《Linux》系列❀❀❀❀❀【Linux系列-P1】Linux环境的搭建【Linux系列-P2】Linux的基本知识与指令【Linux

HTTP、HTTPS协议详解

文章目录HTTP是什么报文结构请求头部响应头部工作原理用户点击一个URL链接后,浏览器和web服务器会执行什么http的版本持久连接和非持久连接无状态与有状态Cookie和Sessionhttp方法:get和post的区别状态码HTTPS是什么ssl如何搞到证书nginx中的部署加密CA数字证书hash算法对称加密非对

热文推荐