学习笔记 – 基础知识 | 每日一面(19)

古代的剑客们与

对手相逢时,无

论对手多么强大,

明知不敌,也要亮出自己的剑!

读者:对于代码 int i = 3; i = i++; 不同编译器给出不同的结果, 有的为3, 有的为 4, 哪个是正确的?

小林:没有正确答案;这个表达式无定义。同时注意,i++ 和 ++i 都不同于 i+1。如果你要使 i 自增 1, 使用 i=i+1, i+=1, i++ 或 ++i,而不是任何组合。

读者:这是个巧妙的表达式: a ˆ= b ˆ= a ˆ= b 它不需要临时变量就可以交换 a 和 b 的值。

小林:这不具有可移植性。它试图在序列点之间两次修改变量 a, 而这是无定义的。例如,有人报告如下代码:

int a = 123, b = 7654;

a ^= b ^= a ^= b;

在 SCO 优化 C 编译器 (icc) 下会把 b 置为 123, 把 a 置为 0。

读者:我可否用括号来强制执行我所需要的计算顺序?

小林;一般来讲, 不行。运算符优先级和括弧只能赋予表达是计算部分的顺序. 在这个代码中:f() + g() * h()。尽管我们知道乘法运算在加法之前, 但这并不能说明这三个函数哪个会被首先调用。如果你需要确保子表达式的计算顺序, 你可能需要使用明确的临时变量和独立的语句。

有时候,正是那些意想不到之人,成就了无人能成之事。——图灵

正文完