根据平台,C代码的输出是否会有所不同?

时间:2015-06-11 16:18:30

标签: c printf

C代码如下。我知道代码会导致核心转储。我们可以看到什么输出?不同的平台有什么不同吗?

#include <stdio.h>

int main(){
    printf("abc\n123");
    printf("IHJ");
    printf("%d", int* 0);
    return 0;
}

4 个答案:

答案 0 :(得分:1)

  

我知道代码会导致核心转储

嗯,遗憾的是,您的信息错误以上代码无法编译。请继续阅读。

您的代码中存在第三个printf()的问题。

  printf("%d", int* 0);

无效且无法编译。 %d需要int 变量,而不是int keyoword本身。

即使int* 意味着cast,例如

printf("%d", (int*)0);

也是错的。您需要%p来打印指针(地址)。为特定格式说明符提供无效类型的参数会调用undefined behaviour

FWIW,当你面对UB时, 可能 会出现分段错误和核心转储。

否则,只要您为printf()提供的格式说明符提供所需的参数类型和数量,就会有明确定义的行为。

要迂腐,int main()应为int main(void)

答案 1 :(得分:1)

printf("%d", int* 0);

这不会编译。如果你的意思是

printf("%d", (int*)0);

然后它也是错误的(使用错误的格式说明符是未定义的行为),因为打印指针的格式说明符是%p。所以你的意思是

printf("%p", (void*) (int*)0);

然后由%p打印的结果表示是实现定义的。

C标准状态

C11,7.21.6格式化输入/输出功能

  

参数应该是指向void的指针。指针的值是   转换为一系列打印字符,在   实现定义的方式。

答案 2 :(得分:0)

如果第三个printf()具有如下所示的确切位置:

printf("%d", int* 0);

这将导致编译器错误。但是,如果你的意思是

printf("%d", (int *)0);

有两个问题:

  • 格式说明符用于整数,而不是指针。如果两者具有相同的大小,您将幸运地获得相同的输出。但它实际上是未定义的行为。使用"%p"作为指针。
  • 另一个问题(更一般)是你传递的是null pointer。由于指针的整个处理是特定于实现,因此printf()可能会处理它与有效指针值的不同。

无论哪种方式,都不能保证核心转储或显示任何特定行为。它甚至可能显示没有错误的行为(最坏的情况 - 你没有注意到出错的地方)。 “未定义行为”的本质是任何事情都可能发生。你的电脑可能会飞走。

答案 3 :(得分:0)

如前所述,

printf( "%d", int* 0 );

不会编译,因为int* 0不是合法表达。

如果写成

printf ( "%d", (int *) 0 );

然后行为 undefined ,因为%d期望其对应的参数具有类型int,而不是int *。这很可能导致核心转储,但任何输出都不应该被信任。

如果写成

printf( "%p", (int *) 0 );

行为仍未未定义,因为%p需要void *(这是您需要将指针值显式转换为{{}的少数几个地方之一C)中的1}}。同样,这很可能导致核心转储,但任何输出都不应该被信任。

如果写成

void *

然后它应该打印出一个NULL指针的实现定义值,该指针可能不是或不是0(假设你使用换行符或调用printf( "%p", (void *) 0 ); ,无论如何)。

如果写成

fflush( stdout )

然后这个很可能导致核心转储。严格来说,由于您要取消引用无效指针,行为仍未定义,并且可能存在这样做的系统不会导致立即崩溃。

相关问题