我正在练习C考试,我对这段代码有疑问。我很清楚,在第一个printf程序中显示第一个未更改的x和y值。但是当我们调用DO时,由于b
,变量x应该更改值并接受(a=b)
的值,最后b
应该具有此b=(25)-15
的值,最后b=10
1}}。但我的程序显示15,15而不是15,10。一些善良的灵魂可以解释一下我在这里做错了吗?
#define DO(a,b) b=(a+b)-(a=b)
int main (void)
{
int x = 10;
int y = 15;
printf ("%d %d\n",x,y);
DO(x,y);
printf ("%d %d\n",x,y);
return 0;
}
答案 0 :(得分:2)
b=(a+b)-(a=b)
您在同一行中执行两项任务,通常是未定义的行为。
你不是说
b=(a+b)-(a-b)
有关序列点的更多信息以及为什么写的是UB can be found here(感谢Axel!)
答案 1 :(得分:2)
您的DO
宏将扩展为:
y = (x+y) - (x=y);
您无法保证首先评估哪些括号。
如果首先评估(x=y)
,它将评估为15(并将x设置为15),因此整个事情将评估为
y = (15+15) - 15;
所以y将设置为15,并打印15, 15
如果首先评估x+y
,表达式将评估为:
y = (10+15) - 15;
y将等于,因此它将打印15, 10
。
因此,行为未定义,因为您没有可确保评估顺序的序列点。有关序列点的更多详细信息(在C ++上,但C是相同的),请查看此处:Undefined behavior and sequence points
答案 2 :(得分:1)
从您的描述看来,您似乎正在尝试使用swap
macro DO
变量
使用下面的宏来交换数字..
#define DO(a,b){ a = a + b; b = a - b; a = a - b; }