当我编译这段代码时,它每次都会给出随机值,而我无法理解变量“i”的效果?
#include<stdio.h>
int main()
{
int j,i=-4,num;
j=(num<0?0:num*num);
printf("%d",j);
return 0;
}
答案 0 :(得分:1)
num
未初始化。这意味着值 未定义或不确定或随机。该值可能是该内存位置中剩余的值。
i
在此计划中没有任何意义
j
。这意味着,如果0
,则值为num < 0
;如果为num * num
,则值为num < 0
。
如果我们写下来,也许对你来说更容易:
if(num < 0)
j = 0;
else
j = num * num;
但由于num
是随机的(未定义的),因此值j
也是随机的。
答案 1 :(得分:0)
因为我们看到在程序中没有使用“i”但仍然影响程序,我知道num没有初始化,这就是为什么我想知道效果和输出
除了num
未初始化并因此导致未定义的行为(意味着,任何事情都可能发生)之外,您还可以通过分析程序集输出来查看技术方面。然而,这是C规范,并且在很大程度上取决于您使用的编译器,底层架构和操作系统。
i
如何影响该计划?
它没有被使用,因此编译器甚至可能决定完全忽略它。但是,在使用gcc
编译代码而没有优化时,我们看到这会向代码添加一条指令:
movl $-4, -12(%rbp)
因此,有两个影响:由于附加指令,生成的目标代码会略大,程序的运行时间会略有增加。如果您使用不同的优化级别,这可能会完全不同。
Num未初始化,这就是为什么我想知道效果和输出
对于自动变量,只分配空间(在堆栈上),但不进行初始化。由于之前可能使用过相同的内存位置(堆栈),因此这些位置可能包含任何内容。因此,输出取决于之前发生的事情,这是不确定的。由于j
是根据num
计算的,因此j
的内容也未定义。
当我删除变量i
时输出生效的原因删除变量i
可能会影响堆栈上的空间分配(因为需要的空间更少),并且可能导致num
重用不同的内存位置,这可能包含一个常量值而不是随机值。但是,这仍然是未定义的,并且随编译器,体系结构和平台而变化,并且取决于之前发生的事情。
可能的堆栈布局i
,第一个字总是包含0x0000
,而第二个字对于每个程序调用都不同:
--------
| 0x0000 | <= memory location assigned to i (will be initialized to -4 in the next step)
+--------+
| 0xnnnn | <= memory location assigned to num (contains a random value)
--------
没有i
的可能堆栈布局:
--------
| 0x0000 | <= memory location assigned to num (randomly "initialized" to 0x0000 by coincidence)
+--------+
| 0xnnnn | (Unused)
--------
但是,我们观察到的一切只是未定义的行为。