1概述
一个C++程序就是一系列数据与操作的集合。当一个C++程序开始运行的时候,与该程序相关的数据就会被加载到内存中。当数据与内存发生关联的时候,这些数据就会具有如下的特性:
- 数据在内存中的地址。这个地址决定了数据在内存中的存储位置。在32位的系统中,每一个C++程序都具有4GB大小的内存地址空间,这个4GB大小的内存空间又被划分为若干个区域,如:栈区,堆区,全局(静态)区,文字常量区,以及程序代码区。不同内存地址的数据将会被存储在不同的内存区域中;
- 数据在内存中的值。如果该值可变,那么该数据就是变量;如果该值不可变,那么该数据就是常量;
- 数据的类型。数据的类型决定了数据占用内存的多少。如:Int型占4个字节,Short型占两个字节;
- 内存分配的时间点。有的数据在编译时由编译器分配内存,这些数据是:全局变量/常量,文字常量,静态变量。在编译阶段,编译器就为这些数据分配了内存,当程序运行的时候,这些数据就会被直接加载到已分配的内存位置上;而有的数据只能在运行时由系统分配内存,如:函数内部的局部变量,以及使用new操作符分配的变量。这些数据的内存地址在程序运行时刻才能确定。
在编码阶段,程序员可以定义各种常量和变量;在编译阶段,编译器会将程序员定义的变量和常量放到不同的数据段中;在程序运行阶段,这些变量和常量又会被加载到不同的内存区域。以下,将从编码阶段,编译阶段,程序运行阶段,三个阶段来说明变量/常量在内存,数据段中的分布情况。
在C++的编码阶段,程序员可以定义各种作用域或生命周期的变量或常量,如:全局变量/常量,静态变量/常量,局部变量/常量,以及使用new操作符分配的变量或常量。
在C++的编译阶段,编译器将在编译时刻能够确定内存地址的变量或常量放到不同的数据段中。在编译后的可执行文件中,一般会包含如下的数据段:
- .text段,该数据段存放程序代码;
- .bss段,该数据段存放未初始化的全局变量或静态变量;
- .data段,该数据段存放已初始化的全局变量或静态变量;
- .rdata段,该数据段存放文字常量,以及在全局作用域中定义的字符常量。
在C++程序的执行阶段,程序代码中定义的变量和常量会被加载到不同的内存区域。如:全局变量,静态变量加载到全局区,文字常量加载到文字常量区。
具体情况如下表所示:
创建时刻 |
程序代码 |
可执行文件 |
内存 |
备注 |
编译时刻 |
已初始化的全局变量,静态变量 |
.data段 |
全局区(初始化) |
可读,可写 |
未初始化的全局变量,静态变量 |
.bss段 |
全局区(未初始化) |
可读,可写 |
|
文字常量 |
.rdata段 |
文字常量区 |
只读 |
|
全局符号常量 |
.rdata段 |
文字常量区 |
只读 |
|
运行时刻 |
局部自动变量,符号常量 |
|
栈区 |
属于线程 |
New操作符分配的变量,常量 |
|
堆区 |
属于进程 |
2常量的分类
2.1文字常量
当一个数值,字符或者字符串,例如 1,’A’,”Test Const”等,出现在程序代码中的时候,它们被称为文字常量。称之为“文字”是因为我们只能以值的形式表述它们;称之为“常量”是因为它们的值不能被改变。文字常量出现在C++代码中,一般为其他变量赋初始值。具体的示例代码如下:
Int a & |