#include<stdio.h>
int main()
{
int a,b;
float e;
char f;
printf("int &a = %u\n",&a);
printf("int &b = %u\n",&b);
printf("float &e = %u\n",&e);
printf("char &f = %u\n",&f);
}
输出
int &a = 2293324 int &b = 2293320 float &e = 2293316 char &f = 2293315
但是当我使用这段代码并将printf替换为float -
时#include<stdio.h>
int main()
{
int a,b;
float e;
char f;
printf("int &a = %u\n",&a);
printf("int &b = %u\n",&b);
printf("char &f = %u\n",&f);
}
然后输出
int &a = 2293324 int &b = 2293320 char &f = 2293319
此处地址未提供给float,但它在顶部声明。 我的问题是
答案 0 :(得分:4)
1)内存是否未分配给程序中未使用的变量?
是的,可以发生,允许编译器对其进行优化。
2)为什么地址按递减顺序分配。前2293324到2293320?
对于大多数本地存储实现而言,它通常使用CPU支持的堆栈指针,从堆栈顶部到堆栈底部。所有这些局部变量最有可能在堆栈中分配。
答案 1 :(得分:2)
1)内存是否未分配给程序中未使用的变量?
这是一个允许的优化;如果未使用的变量不影响程序的可观察行为,编译器可能只是完全丢弃它。请注意,大多数现代编译器会警告您未使用的变量(因此您可以从代码中删除它们或使用它们执行某些操作)。
2)为什么地址按递减顺序分配。 ex-它从2293324到2293320?
编译器不需要以任何特定顺序为单独的对象分配存储空间,因此不要假设您的变量将按照它们声明的顺序进行分配。此外,请记住,在x86和其他一些系统上,堆栈“向下”向减少地址增长。请记住,任何堆栈的顶部只是最近推送某些内容的位置 - 它与相对地址值无关。
答案 2 :(得分:0)
虽然标准没有特别要求,但局部变量通常位于程序堆栈上。
当你输入一个函数时,首先要做的就是减少堆栈指针,为局部变量提供空间。
SUBL #SOMETHING, SP
其中SOMETHING是所需的空间量,SP是堆栈指针寄存器。在你的第一个例子中,SOMETHING可能是13.然后地址:
f is 0(SP)
e is 1(sp)
b is 5(sp)
a is 9(sp)
我假设你的编译器没有对齐堆栈指针。通常他们会提供更多类似的东西:
f is 3(SP)
e is 4(sp)
b is 8(sp)
a is 12(sp)
在32位系统上,SOMETHING会被四舍五入为。
您可能希望使用编译器生成程序集列表,以查看其下的内容。
内存是否未分配给程序中未使用的变量?
请注意,对于本地变量,内存并未真正分配。变量临时绑定到程序堆栈上的某个位置(标准不需要堆栈,但在大多数情况下它是如何完成的)。这就是变量初始值未定义的原因。它本来可能与其他东西绑定。
编译器不需要为未使用的变量保留空间。它们可以被优化掉。通常,有一些编译器设置可以指示不要进行调试。
为什么地址按递减顺序分配。 ex-它从2293324到2293320?
程序堆栈通常会向下增长。从那天开始,程序将位于地址空间的底部,堆上方的堆和相反端的堆栈。
堆会朝着更高的地址增长。堆栈将朝向堆(较低地址)增长。
虽然地址空间可能比现在更复杂,但堆栈的下降仍然存在。
没有特别要求编译器按降序将变量映射到堆栈,但有50/50的可能性会以这种方式执行。