6

我对 C 编程不太熟悉(我只用该语言做过几个小项目),但是,我的教授今天谈到了它的行为,这让我有点困惑。

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

    int a = ___________;
    int b = ___________;

    if (a < b)
   print (“&lt;“);
    if (a > b)
   print (“&gt;”);
    if (a==b)
   print(“=”);

基本上,您可以在不满足这些条件的那些 int 变量中存储一些东西(_ __ _显然不是实际代码,它只是表示存在某些东西)。它不一定需要是一些填补这些空白的整数......它可以是世界上的任何东西(并且可能在这段代码之前发生了一些事情)。

是什么可以填补这些空白而不会产生任何结果,为什么?

ps - 它与溢出、未定义的行为、越界错误或类似情况有关

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

4

8 回答 8

4

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

int b = *(int *)0;
于 2011-05-13T10:27:52.313 回答
2

我想重要的是_部分。如果下划线部分包含代码结果未定义行为,并且带有比较的以下代码由“聪明”编译器优化未定义行为,则这段代码的最终行为是未定义的。不打印任何东西是一种合理的未定义行为。

ps 根据维基百科,除以零会导致未定义的行为,尽管大多数编译器将其定义为错误。并且 IIRC 有符号整数溢出也会导致未定义的行为,尽管这通常会导致运行时异常甚至编译错误。所以如果 a 和 b 被声明为

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

你的教授描述的情况可能会发生。但请记住,行为是未定义的,因此无论编译器选择程序来表现什么,都可能被认为符合标准。

于 2011-05-13T10:17:18.330 回答
1

如果您的架构在一个补码中包含 int 数,则存在两个零:一个所有位设置为 0,一个所有位设置为 1,即正零和负零。两个零应该比较相等,但是有问题的编译器可能看不到这样;-)

于 2011-05-13T10:28:40.417 回答
0

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

于 2011-05-13T10:22:40.000 回答
0
a = 0, b = 5 / a : divide by zero
于 2011-05-13T10:39:59.617 回答
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;
}
于 2011-05-13T10:45:02.853 回答
0

可能的定义print是:

void
print(const char*) {    
}
于 2011-05-13T11:02:00.967 回答
0

ps - 它可能与溢出有关?

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

#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 引入的固定大小整数和小数字大小,因此我们可以在脑海中进行操作。

于 2011-05-13T10:25:20.987 回答