printf() 中的赋值运算符问题

Posted

技术标签:

【中文标题】printf() 中的赋值运算符问题【英文标题】:issue with assignment operator inside printf() 【发布时间】:2015-10-14 01:02:31 【问题描述】:

这里是代码

int main()

  int x=15;
  printf("%d %d %d %d",x=1,x<20,x*1,x>10);
  return 0;

输出是1 1 1 1

我期待 1 1 15 1 作为输出,

x*1 等于 15 但这里 x*11 ,为什么? 在printf() 中使用赋值运算符或修改值会导致undefined behaviour

【问题讨论】:

您明确设置了x=1。我不确定你还能期待什么。 虽然不是问题的直接重复,但Why are these constructs using pre and post-increment undefined behavior? 的答案也确实深入解决了这个问题。 【参考方案1】:

您的代码会产生未定义的行为。函数参数求值不是相对于彼此排序的。这意味着在x=1 中修改对x 的访问与其他访问不相关,例如x*1 中的访问。行为未定义。

再一次,它是未定义的,不是因为您“使用赋值运算符或修改 printf() 中的值”,而是因为您对未排序与其他访问相关的变量进行了修改访问到同一个变量。这段代码

(x = 1) + x * 1

出于同样的原因也有未定义的行为,即使其中没​​有printf。同时,这段代码

int x, y;
printf("%d %d", x = 1, y = 5);

完全没问题,即使它“使用赋值运算符或在 printf() 中修改值”。

【讨论】:

【参考方案2】:

在函数调用中,函数参数可以按任何顺序计算。

由于其中一个参数修改了x,而其他参数访问它,结果是不确定的。

【讨论】:

【参考方案3】:

标准规定;

在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的评估修改一次。此外,只能访问先验值以确定要存储的值。

它不会对子表达式施加求值顺序,除非它们之间有一个序列点,而不是需要一些未指定的求值顺序,it says that modifying an object twice produces undefined behaviour

【讨论】:

以上是关于printf() 中的赋值运算符问题的主要内容,如果未能解决你的问题,请参考以下文章

赋值运算符

自增运算符和赋值运算符的优先级及运算问题

运算符和条件结构

12 赋值运算符

C中赋值运算符的关联性

C语言中的赋值语句