可以准确地说在
void f() {
int x;
...
}
“ int x;
”表示在栈上分配sizeof(int)
字节?
有什么规格吗?
标准中没有任何内容要求存在堆栈。标准中没有任何内容要求局部变量需要为其分配内存。该变量可以放在寄存器中,甚至可以作为优化完全删除。
没有关于此的规范,您的假设通常(但不总是)是错误的。考虑一些代码,例如
void f() {
int x;
for (x=0; x<1000; x++)
{ // do something with x
}
// x is no more used here
}
首先,优化编译器将放入x
机器的某个寄存器中,并且不消耗任何堆栈位置(除非您对地址执行某些操作,&x
例如将其存储在全局中)。
编译器也可以展开该循环,并x
从生成的代码中删除。例如,许多编译器会替换
for (x=0; x<5; x++) g(x);
相当于
g(0); g(1); g(2); g(3); g(4);
也许替换
for (x=0; x<10000; x++) t[x]=x;
有类似的东西
for (α = 0; α < 10000; α += 4)
{ t[α] = α; t[α+1] = α+1; t[α+2] = α+2; t[α+3] = α+3; };
其中 α 是一个新变量(或者可能是x
它本身)。
此外,可能没有堆栈。对于 C 来说,这是不常见的,但其他一些语言没有任何堆栈(例如,参见旧的 A.Appel 的书 compile with continuations)。
顺便说一句,如果使用GCC ,您可以使用例如MELT 探针(或使用gcc -fdump-tree-all
它产生数百个转储文件!)来检查它的中间(Gimple)表示。
来自GNU:
3.2.1 C 程序中的内存分配
当您声明一个自动变量(例如函数参数或局部变量)时,就会发生自动分配。自动变量的空间在输入包含声明的复合语句时分配,并在退出该复合语句时释放。在 GNU C 中,自动存储的大小可以是一个变化的表达式。在其他 C 实现中,它必须是常量。
这取决于很多因素。编译器可以优化并从堆栈中删除它,将值保留在寄存器中。等等
如果您在调试中编译,它肯定会在堆栈中分配一些空间,但您永远不知道。这没有具体说明。唯一指定的是变量的可见性以及它的大小和算术。查看C99 规范以获取更多信息。
我认为这取决于编译器。我为 Code::Blocks 和 Dev-C++ 使用了默认编译器,看起来内存是在初始化期间分配的。在以下 cout 语句中,将 n2 更改为 n1 将给出相同的答案。但是如果我将 n1 初始化为某个值,或者如果我在显示平均值之前显示 n2,我会得到一个不同的答案,它是垃圾。请注意,由于变量未初始化,VS 确实通过给出错误来正确处理此问题。
void getNums();
void getAverage();
int main()
{
getNums();
getAverage();
return 0;
}
void getNums()
{
int num1 = 4;
double total = 10;
}
void getAverage()
{
int counter;
double n1 , n2;
cout << n2/counter << endl;
}