[英]Query on activation record in C
下面是我不明白的代码。
#include<stdio.h>
int main(int argc, char *argv[])
{
int num;
printf("\n Number: " );
scanf("%d", &num);
if (num >= 0)
{
int abs = num;
}
else
{
int abs = -num;
}
{
int abs;
printf("\n Values are %d %d", num ,abs);
}
return 0;
}
当我输入数字4时,输出为Values are 4 4
当我输入数字-4时,输出为Values are -4 4
我无法理解如何打印绝对值? if循环和else循环中定义的变量abs在退出后应该已经被释放。
请让我知道。
问候,ie
你是绝对正确的。
您是否看到最后一次声明int abs
的最后一个块? 请注意, abs
尚未初始化,使用未初始化的变量会产生未定义的结果。 对于您的特定编译器,您碰巧会碰运气,而新abs
所在的内存块仍然包含来自(已过期)先前范围的结果。
这些变量是在堆栈上分配的,但您没有对其进行修改,我的意思是您没有离开函数,因此,以编程方式,您将在最后一个代码块中获得“ new”“ abs” int,但是实际上,此“新”“ abs” int位于旧“ abs”所在的位置(在堆栈上!),因此其默认值相同。
这就是所谓的“不确定行为”。
用printf
声明abs
时,您将得到“堆栈垃圾”。
它是这样的:
if (num >= 0) {
create 'abs' at memory address N, put 'num' in it.
destroy 'abs' // but leave the 'garbage' at memory address N
} else {
create 'abs' at memory address N, put '-num' in it.
destroy 'abs' // but leave the 'garbage' at memory address N
}
{
create 'abs' at memory address N, don't put anything in it.
// your compiler has decided it will reuse N. That's a valid choice.
// your compiler has decided it will not zero the memory at address N. That's valid.
read whatever was at 'abs'. // it's whatever was assigned in the conditional.
}
始终使用-Wall
编译:)
您在printf中使用未初始化的abs值。 C语言标准不需要特别说明,因为它尚未初始化。 可以是0、1或-32765
在这种特殊情况下,您可能会得到相同的数字,因为编译后的代码将abs的临时值重新使用一个寄存器,而printf块中的abs变量再次使用了相同的寄存器。
您可以查看反汇编代码,以准确地了解编译器根据机器指令执行的操作。
搞笑代码。
它依赖于以下事实:由于编译器优化,abs的所有三个定义都将分配在堆栈上的同一位置。
第三个ab必须是随机garbag,结果表明垃圾是前一个具有相同名称的变量的结果(名称无关紧要)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.