C程序:输出似乎令人困惑

时间:2011-03-03 13:36:30

标签: c

#include<stdio.h>  
#include<conio.h>  
#define SQUARE(x) (x*x)  
void main()  
{  
    clrscr();  
    int i=3,j,k;  
    j=SQUARE(i++);  
    k=SQUARE(++i);  
    printf("\n%d\n%d\n%d",j,k,i);  
    getch();  
}  

回答令人困惑:9 49 7 我在想j = 3 * 4 = 12,k = 6 * 7 = 42,i = 7 发生了什么事?我错过了什么吗? (x * x)=((x)*(x))这里相同。没关系。

1 个答案:

答案 0 :(得分:8)

这两行:

#define SQUARE(x) (x*x)  
j=SQUARE(i++); 

转换为:

j = (i++ * i++);

这是未定义的行为。如果没有插入序列点,则不允许修改变量两次(并且*不是序列点)。

你最好使用类似的东西:

inline int SQUARE (int x) { return x * x; }

可能发生的事情是增量在乘法完成之后或之前一起发生,有效地为您提供:

i = 3;                  // i = 3
j = i * i; i++; i++;    // j = 9, i = 5
++i; ++i; k = i * i;    // i = 7, k = 49

但请记住,这是在这种情况下发生的事情。由于您违反规则,实现可以自由地以其他方式执行。实际上,它可以根据需要格式化您的硬盘。这是未定义行为的本质,​​定义为(我的斜体):

  

行为,在使用不可移植或错误的程序结构或错误数据时,本国际标准强加 no 要求。

     

注意可能的未定义行为包括完全忽略具有不可预测结果的情况在翻译或程序执行期间以环境特征的文档化方式运行(有或没有发出诊断消息) ,终止翻译或执行(发布诊断信息)。