#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))这里相同。没关系。
答案 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 要求。
注意可能的未定义行为包括完全忽略具有不可预测结果的情况,在翻译或程序执行期间以环境特征的文档化方式运行(有或没有发出诊断消息) ,终止翻译或执行(发布诊断信息)。