用C实验

时间:2016-05-06 20:00:51

标签: c

#include<stdio.h>

int main() {
    int x = 99;
    printf("%d %d\n",1 > scanf("%d",&x) ? scanf("%d",&x): scanf("%d",&x),x);
}

那么扫描值发生了什么。 让我们说First Input是11.所以最左边的scanf返回1.所以根据规则,最右边的scanf将被执行。但是printf的最右边%d不打印扫描值。它显示99。

2 个答案:

答案 0 :(得分:5)

您有未定义的行为

这是因为您正在修改值并访问该值而没有插入序列点。一个具有相同问题的简化示例:

int x, y;
x = 1;
y = scanf("%d", &x) + x; /* <--- UB! */

或者:

int x = 1;
printf("%d %d", x = 11, x); /* <--- UB! */

请注意,虽然?:确实在条件之后插入了一个序列点,但是在函数调用中分隔参数的逗号却没有。这个测量,不仅是函数参数的评估顺序是未指定的,而且你不能在函数的参数中修改相同的值两次,或者修改和使用相同的参数。

例如,另一个例子也是UB:

int x = 0;
printf("%d %d", x++, x); /* <--- UB! */

或者这个:

int x[10] = {0}, i = 0;
printf("%d %d", x[i++], x[i++]); /* <--- UB! */

您的问题的解决方案是将代码分成漂亮有序的句子。完整的句子总是以序列点结束!

int x = 99;
int y = 1 > scanf("%d",&x) ? scanf("%d",&x): scanf("%d",&x); /* ARGH! */
printf("%d %d\n", y, x);

现在,标有感叹号的行是非常荒谬的,但至少它没有UB。

答案 1 :(得分:2)

可以按任何顺序评估函数参数。在这种情况下,在调用scanf之前,x的计算结果为99。函数参数评估的顺序在C中未指定。这是C FAQ #3.7

  

逗号运算符确保从左到右的评估,但在函数调用中分隔参数的逗号不是逗号运算符。 [...]未指定函数调用的参数的评估顺序。

因为修改 x的scanf与评估的函数参数之间没有序列点,所以你正在调用未定义的行为,如rodrigo&#39;中所述。答案。