数字比较中的歧义(C)?

数字比较中的歧义(C)?,c,comparison,int,ambiguity,C,Comparison,Int,Ambiguity,我不太熟悉C语言的编程(我只用C语言做过几个小项目),但是,我的教授今天说了一些关于它的行为的话,这让我有点困惑 他所说的是,这段代码有时根本不会打印任何东西(我完全复制了黑板上的内容,我相信这是C的伪代码,因为C中没有“打印”): int a=\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu; int b=uuuuuuuuuuuuuuuuuuuuuuuu; if(a”); 如果(a==b) 打

我不太熟悉C语言的编程(我只用C语言做过几个小项目),但是,我的教授今天说了一些关于它的行为的话,这让我有点困惑

他所说的是,这段代码有时根本不会打印任何东西(我完全复制了黑板上的内容,我相信这是C的伪代码,因为C中没有“打印”):

int a=\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu;
int b=uuuuuuuuuuuuuuuuuuuuuuuu;
if(a”);
如果(a==b)
打印(“=”);
基本上,你可以在这些int变量中存储一些东西,而这些条件都不满足(显然,\uuuuuuuuuuuuuuuuu>不是实际的代码,它只是表示存在一些东西)。它不一定需要一些int数来填充这些空白……它可以是世界上的任何东西(这段代码之前可能发生过一些事情)

是什么填补了这些空白,却不会产生任何结果,为什么

p、 它与溢出、未定义的行为、越界错误等有关

p、 p.s-我很难相信这位教授是错的。他比我接触过的任何人都更了解编程。我确信在某些情况下这是真的。

我想重要的是\uu部分。如果下划线部分包含代码结果未定义的行为,那么下面的代码通过“聪明”的编译器对未定义的行为进行优化,这段代码的最终行为是未定义的。不打印任何内容是合理的未定义行为

p、 根据Wikipedia,被零除会导致未定义的行为,尽管大多数编译器将其定义为错误。IIRC带符号整数溢出也会导致未定义的行为,尽管这通常会导致运行时异常甚至编译错误。因此,如果a和b声明为

int a = 1 / 0;
int b = INT_MAX + 1;

您的教授描述的情况可能会发生。但请记住,行为是未定义的,因此编译器选择程序的行为可能被视为符合标准。

对于int,这是不正确的,因为它们没有“特殊”值

p、 它可能与溢出有关

我想这就是你教授的意思:

#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;
}
#包括
#包括
int main(int argc,字符**argv)
{
uint8_t a=100;
uint8_t b=200;
a=a+b;/*a=300在你的头脑中。这会溢出,所以300-256=44*/
如果(a>b)
{
printf(“%u>%u”,a,b);
}
否则如果(a
具体地说,我使用的是一个固定宽度的8位无符号整数,它的最大值为8位(令人惊讶),表示256为可能的最大整数。您可以通过向该字段中添加此大小无法表示的量来溢出该字段,在这种情况下,剩下的是环绕效应

由于if比较逻辑实际上是处理器的一部分(if转换为比较/跳转指令组合之一),因此if比较逻辑中没有实际的歧义问题是,你可能已经合理地对它进行了编程,希望它能工作,但没有意识到计算机上的数字表示都有固定的表示。我看不到我能放入那些寄存器的任何东西,这些东西可能会逃过所有的“少、大或相等”


注:为了清晰起见,我使用了C99引入的固定大小整数和较小的数字大小,这样我们就可以在头脑中进行操作。

所有必要的是其中一个int初始化生成运行时异常。然后,程序将在任何比较测试之前终止。例如

int b = *(int *)0;

如果您的体系结构中的整数是1的补码,那么就存在两个零:一个是所有位都设置为0,另一个是所有位都设置为1,也称为正零和负零。两个零的比较应该相等,但一个有缺陷的编译器可能看不到这一点;-)

假设“在这段代码之前可能会发生一些事情”

#包括
#包括
内部主(空)
{
#定义整型浮点
int a=nanf(空);
int b=nanf(空);
if(a
也许打印的定义是:

void
print(const char*) {    
}

你的教授错了。可能混淆了关于浮点比较的一句话,C ManI我肯定这是一个int(而且,我肯定他指的不是NaN)。有两种选择:1.你的教授错了2.你误解了他说的话。我会尽快问我的教授(每个人都不相信我,这无疑提高了我寻找答案的兴趣)。遗憾的是,我要到周二才能见到他。如果到那时还没有人解决这个问题,我会在周二告诉你们他说了什么。他说教授声称这个代码有时根本不会打印任何东西,这个代码打印“44<200”是的,会的。但即使使用有符号类型,你也只是在修改寄存器。我想不出任何可能失败的方法,即使你将指针与整数进行比较,因为寄存器中的指针只是一个数字。我只能认为他一定是想说明整数溢出的问题。补码中的负零不是吗符合特殊条件?或者您已经用一个不做任何事情的函数替换了
print
。或者,您只需
返回0;
,如果答案符合这些条件,则可以将
替换为任何东西,例如
int a=calltofunction返回到butsegfaults()
或者甚至
int a=1;退出(0);
@murrekatt:很好,但请注意,对于C89来说,答案必须是
int b=1;退出(0);
很好,但我怀疑这是他的意思(因为他是c
a = 0, b = 5 / a : divide by zero
#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;
}
void
print(const char*) {    
}