繁体   English   中英

查询C中的激活记录

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM