我对C语言编程不太熟悉(我只用语言完成了一些小项目),然而,我的教授今天说了一些关于它的行为让我有些困惑。
他说的是这段代码有时根本不会打印任何内容(我完全复制了主板上的内容,我相信这是C的伪代码,因为“print”不在C中):
int a = ___________;
int b = ___________;
if (a < b)
print (“<“);
if (a > b)
print (“>”);
if (a==b)
print(“=”);
基本上,你可以在那些没有满足这些条件的int变量中存储一些东西( _ __ _ isn显然,实际的代码,它只代表某些东西存在)。它不一定需要一些填充那些空白的int数字......它可能是世界上的任何东西(并且可能存在在此代码之前发生的事情)。
什么能够填补这些空白并且不会产生任何结果,为什么?
p.s - 它与溢出,未定义的行为,超出范围的错误或类似的东西有关
p.p.s - 我很难相信这位教授错了。他比任何我接触过的人都更了解编程。我确信在某些情况下这是真的。答案 0 :(得分:4)
所有必要的是int初始化之一生成运行时异常。然后程序将在任何比较测试之前终止。 E.g。
int b = *(int *)0;
答案 1 :(得分:2)
我想重要的是 _ 部分。如果带下划线的部分包含代码结果UNDEFINED行为,并且以下带有比较的代码通过“聪明”编译器得到优化且未定义的行为,则这段代码的最终行为是未定义的。而不打印任何东西都是一种合理的未定义行为。
P.S。根据维基百科,除零行为导致未定义的行为,尽管大多数编译器将其定义为错误。并且IIRC签名的整数溢出也会导致未定义的行为,尽管这通常会导致运行时异常甚至编译错误。所以如果a和b被声明为
int a = 1 / 0;
int b = INT_MAX + 1;
您的教授描述的情况可能会发生。但请记住,行为是未定义的,因此无论编译器选择程序行为,都可能被认为符合标准。
答案 2 :(得分:1)
如果你的结构中有一个带有int数的补码,则存在两个零:一个所有位设置为0,另一个所有位设置为1,即正零和负零。两个零都应该相等,但是一个错误的编译器可能看不到这一点; - )
答案 3 :(得分:0)
对于int,这不是真的,因为它们没有“特殊”值。
答案 4 :(得分:0)
p.s - 它可能与溢出有关吗?
我认为这就是你教授的意思:
#include <stdio.h>
#include <stdint.h>
int main(int argc, char** argv)
{
uint8_t a = 100;
uint8_t b = 200;
a = a + b; /* a = 300 in your head. This overflows, so 300-256=44 */
if ( a > b )
{
printf("%u > %u", a, b);
}
else if ( a < b )
{
printf("%u < %u", a, b);
}
else
{
printf("%u == %u", a, b);
}
return 0;
}
具体来说,我使用的是固定宽度的8位无符号整数,它最多可以保存8位(惊喜),它表示256是最大可能的整数。你可以通过添加一个无法用这个大小表示的数量来溢出这个字段,在这种情况下,你剩下的是一个环绕效果。
if比较逻辑中没有实际的歧义,因为它实际上是处理器的一部分(如果转换为比较/跳转指令组合之一)。问题是你可能已经合理地预期它可以工作,而不是意识到计算机上的数字表示都有固定的表示。我看不到任何可以放入那些可能会逃脱“更少,更大或更平等”的寄存器。
注意我使用了C99引入的固定大小整数来表示清晰度和较小的数字大小,所以我们可以在头脑中进行。
答案 5 :(得分:0)
a = 0, b = 5 / a : divide by zero
答案 6 :(得分:0)
鉴于“在此代码之前可能会发生一些事情”......
#include <stdio.h>
#include <math.h>
int main(void)
{
#define int float
int a = nanf(NULL);
int b = nanf(NULL);
if (a < b)
printf("<\n");
if (a > b)
printf(">\n");
if (a == b)
printf("==\n");
return 0;
}
答案 7 :(得分:0)
也许print
的定义是:
void
print(const char*) {
}