【问题标题】:integer arithmetic inside printf()printf() 中的整数运算
【发布时间】:2019-02-18 23:10:54
【问题描述】:

C 编程新手。为什么下面这段代码的输出不是0 20 0而是1 20 0

printf ( "\n%d %d %d", x != 1, x = 20, x < 30 ) ;

我的理解是代码将 x 分配给 1 以外的值(1=true 因此!= true 为 0)?有人可以引导我理解逻辑吗?

【问题讨论】:

  • 每个参数的求值顺序未定义。
  • 如果 x 不等于 1,你在测试之前给 x 赋值了什么?
  • 如果你像这样使用 GCC:cc -Wall -W -pedantic 那么你会收到这样的警告warning: operation on ‘x’ may be undefined [-Wsequence-point]

标签: c integer-arithmetic


【解决方案1】:

我不知道为什么某些教育系统会如此流行地选择更具创造性的方法来教授具有未指定行为的不良代码,但是由于未指定评估这些参数的顺序,因此您的程序的行为是未定义的。

也就是说,您可能假设代码是从左到右或从右到左“运行”的,但不需要这样的事情。事实上,anything can happen,包括任何输出或谋杀我的任何家人。所以请不要!

【讨论】:

  • 不可能发生任何事情。 C 标准或其他规范的唯一权力是定义或保留定义。他们无法许可违反其他文件或自然、数学或人类法则的行为。以这种方式表达它传达了一个概念,即行为未由 C 标准定义的程序的行为无法分析,因此无法调试。但事实并非如此。错误程序的行为,包括其输出、陷阱和内存转储,可能包含与编译器设计交互等有助于诊断的线索。
  • 更好的措辞是简单地说“C 标准没有定义行为。”
  • @EricPostpischil 未定义的行为可能非常可怕。即使没有代码显式调用它,也有一个执行函数的示例程序,因为该函数调用只是不是未定义行为的路径。因此编译器假定必须设置函数指针并且必须调用该函数。危险是真实的。反正有些危险。这将取决于那些从未被调用的代码(哈哈)做了什么。
  • @EricPostpischil 这几乎不可能发生,尽管比众所周知的鼻子恶魔更有可能发生。然而,没有任何保证意味着正是
  • @EricPostpischil 请参考我的最后一段here。分析 UB can absolutely be fascinating and educational 的特定“案例”的原因,但老实说,这是有时间和地点的,在我看来,这不是它。当然,请随意写一个对比鲜明的答案!
猜你喜欢
  • 2014-08-23
  • 1970-01-01
  • 2015-10-14
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 2013-07-30
相关资源
最近更新 更多