a++怎么还是3???
a++怎么还是3???
我不得不再说一遍:这个题是错的!
你先要明白前置自增运算符和后置自增运算符是怎么回事:
通常说,a++是先取值后运算,++a是先运算后取值。实际上这里涉及“运算符”、“表达式”和“语句”的概念。
++ 是一个“自增运算符”,自增运算符有两种形式:前置自增(++a)和后置自增(a++)。
运算符和操作数合起来就是一个表达式(a++、++a都是表达式,a就是操作数)。注意:每一个表达式本身都有值(和其类型),有的表达式还有“副作用”。比如自增表达式的副作用就是使其操作数自增1。那么自增运算表达式的值是什么呢? a++ 的值就是 a 的值,而 ++a 的值等于 a+1。
表达式后面加上一个分号才是一个完整的“语句”。
还有一个关键内容:前面说使操作数自增1是自增表达式的副作用,那么这个副作用什么时候发生呢? 准确地说是在“序列点”后保证会发生。 序列点这个概念比较复杂,简单地说:“语句结束时”是一个序列点。这序列点之前的运算符的副作用,在执行到这点以后都保证会发生。注意并不是在这一点之后就突然发生的,这些副作用可能在序列点前的任何一个位置发生,C标准只是规定在序列点之后这些副作用必须已经发生了。
复合表达式中的运算顺序是由运算符优先级决定的,但参与运算的操作数的求值顺序是未定的。
在a+b%a-b/a+a*b-a++这个大复合表达式中,根据运算符优先级,a++先算,这个子表达式的值是3没有错(因为是先求值再自增),但a++的副作用在什么时候发生是并不确定的,且其他的a是什么时候取值也是不确定的。我只知道在整个语句结束之后a的值肯定是4,但a也可能在取第一个a的值时就已经是4了......也可能第一个a还是3,第二个a就是4了......也可能所有的a都是3......这一切都是有可能的,所以这段代码的行为就是未定义的。
对于写复合表达式,一般建议:如果表达式改变了一个操作数的值,那就不要在这个复合表达式中再次使用这个操作数。除非你能确定“改变值”和“使用值”的先后顺序。 在这个例子中,显然你不能确定顺序。
举报