我想知道常量变量存储在哪里。它是存储在与全局变量相同的内存区域吗?还是在栈上?
我想知道常量变量存储在哪里。它是存储在与全局变量相同的内存区域吗?还是在栈上?
它们的存储方式是实现细节(取决于编译器)。
例如,在GCC编译器中,在大多数机器上,只读变量、常量和跳转表会被放置在文本段中。
根据特定处理器遵循的数据分段方式,我们有五个段:
请注意,数据段和BSS段之间的区别在于前者存储已初始化的全局和静态变量,而后者存储未初始化的全局和静态变量。
现在,为什么要谈论数据分段,而不是告诉常量变量存储在哪里...其中有一个原因...
每个段都有一个写保护区域,其中存储所有常量。
例如:
总之,“const”只是一个数据限定符,这意味着首先编译器必须决定变量应存储在哪个段中,然后如果该变量为const,则符合存储在该特定段的写保护区域的条件。
考虑以下代码:
const int i = 0;
static const int k = 99;
int function(void)
{
const int j = 37;
totherfunc(&j);
totherfunc(&i);
//totherfunc(&k);
return(j+3);
}
通常情况下,i
可以存储在文本段中(它是一个带有固定值的只读变量)。 如果它不在文本段中,则将存储在全局变量旁边。 鉴于它被初始化为零,它可能在“bss”节(通常分配清零变量的地方)或“data”节(通常分配初始化变量的地方)中。
如果编译器确信 k
没有使用(因为它局部于单个文件),则它可能根本不会出现在目标代码中。 如果没有注释掉引用 k
的 totherfunc()
调用,则必须在某个位置分配 k
的地址 - 它很可能在与 i
相同的段中。
常量(如果是常量,它还是变量吗?)j
最有可能出现在传统 C 实现的堆栈上。(如果您在 comp.std.c 新闻组中提问,有人会提到标准并未说明自动变量出现在堆栈上;幸运的是,SO 不是 comp.std.c!)
请注意,我强制让这些变量出现,因为我通过引用传递它们 - 大概是给一个期望指向常量整数的指针函数。 如果从未取得地址,那么 j
和 k
可能会被优化出代码。 要删除 i
,编译器必须知道整个程序的所有源代码 - 它在其他翻译单元(源文件)中是可访问的,因此不容易被删除。 特别是如果程序涉及动态加载共享库-其中一个库可能依赖于全局变量。
(在样例中,变量 i
和 j
的命名应更具有意义和长度。)
j
可以被视为一个变量。在 C
中,"variable" 这个词没有定义,但在 C++ 中,j
是一个变量。variable
只是一个命名的对象,无论它是否是 const。在 C 中,字面值和枚举被称为 constants
- 我不认为 j
在 C 中被称为 "constant",因为它不能出现在常量表达式中。 - Johannes Schaub - litb (I) large static and global and non constants and non initilaized variables it stored .BSS section.
(II) second thing small static and global variables and non constants and non initilaized variables stored in .SBSS section this included in .BSS segment.
2) 数据段是已初始化变量,它有三种类型,
(I) large static and global and initlaized and non constants variables its stord in .DATA section.
(II) small static and global and non constant and initilaized variables its stord in .SDATA1 sectiion.
(III) small static and global and constant and initilaized OR non initilaized variables its stord in .SDATA2 sectiion.
我提到过,小和大的意思取决于编译器。例如,小意味着小于8个字节,大意味着大于8个字节和相等的值。
但我的疑问是,本地常量存储在哪里????
它可能根本不会被存储。
考虑以下代码:
#import<math.h>//import PI
double toRadian(int degree){
return degree*PI*2/360.0;
}
这使得程序员能够了解正在发生的事情,但编译器可以优化掉其中的一些内容,大多数编译器通过在编译时评估常量表达式来实现这一点,这意味着PI的值可能根本不会出现在生成的程序中。