《你必须知道的495个C语言问题》读书笔记之第3章:表达式

1. C语言的设计目标之一就是高效的实现——让C语言的编译器相对较小,容易写成,同时也更容易生成较好的代码。

2. Q:下面的代码打印出49.不管按什么顺序,难道不该是56吗?

int i = 7;
printf("%d
", i++ * i++);

    A:尽管后缀自加和后缀自减操作符在输出其旧值之后才会执行运算,但这里的“之后”的含义常常被误解。无法保证自增或自减会在放弃变量原值之后和对表达式其他部分进行计算之前立即进行,只能保证变量的更新会在表达式“完成”之前的某个时刻(下一个“序列点”之前)进行。本例中,编译器选择使用变量的旧值相乘之后再对二者进行自增运算。

3. Q:怎样才能理解复杂表达式并避免写出未定义的表达式,“序列点”是什么?

    A:序列点是一个时间点,此刻尘埃落定,所有的副作用都已确保结束。C语言标准中提及的序列点包括:(a)完整表达式的尾部;(b) ||, &&,?:或逗号操作符处;(c) 函数调用时(参数求值完毕,函数被实际调用之前)。C标准中描述:“在上一个和下一个序列点之间,一个对象所保存的值至多只能被表达式的求值修改一次。而且只有在确定将要保存的值时才能访问前一个值”。第二句话可以这样理解:如果某个对象需要写入一个完整表达式中,则在同一表达式中对该对象的访问应该只局限于用于计算将要写入的值。"i=i+1"之所以合法,是因为对i的访问只是为了计算i的最终值,而a[i] = i++非法是因为对i的访问(a[i])与最终存储在i中的值毫无关系,这样导致没有什么好办法来决定这次访问应该放在i的自增之前还是之后。

原文地址:https://www.cnblogs.com/wuhualong/p/ReadingNote_C_Programming_FAQs_Chap3.html