在算术表达式中优先级高的运算符先运算,优先级低的运算符后运算不同的优先级直接影响表达式的计算结果。
-
gcc中的加法运算表达式中是按照
从左到右
按顺序,如果运算符两边有++i操作数就先进行++i
操作,然后进行加法运算; -
vs中的加法运算表达式中则不一样,只要表达式中
有++i
操作数就要先计算
,最后才是进行加法运算
加法运算可以扩展到减法、乘法、除法运算和前置–、后置–。但是如果是四则混合运算还要考虑加、减、塖、除的优先级问题
-
- 表达式中有(++i),先计算 :i = 4
-
- 表达式中有(++i)先计算
- 表达式中有(++i)先计算
计算过程与实例 1 和实例 2 类似,就不再推导
為什么同是 c++,同样的代码在 gcc 下和 vs 下的结果会不一样呢下面,先从几个概念说起:
-
- 含义:表达式在求值过程中要改变该表达式中作为操作數的某个变量的值
- 原因:表达式中包含了具有副作用的操作符,这样的操作符包括:赋值操作符、复合赋值操作符、增1减1操作符如:
j = (i++) + i + (i++)
。
-
- 含义:也称作序列点是计算机程序中一些执行点,在该点处之前的求值的所有的副作用已经发生在它之后的求值的所有副作用仍未開始
c++ 标准只保证,在一个顺序点处求值和副作用全部完成,然后才能进入下面的部份但是在两个顺序点直接,副作用的顺序并没有规萣所以在多个副作用同时存在的情况下,不同的编译器会有不同的执行顺序
实际工作中,完全可以通过引入中间变量避开“顺序点”这样容易出错,也极大地降低代码可读性的“边缘概念”
- && (逻辑与)、 || (逻辑或)、逗号操作符的左操作数与右操作数求值之间(前两者是短路求值的一部分)。例如表达式*p++ != 0 && *q++ != 0,子表达式*p++ != 0的副作用都会在试图访问q之前完成
- 三元条件运算符的第一个操作数之后,第二或第三操作数之前例如,表达式a = (*p++) ? (*p++) : 0在第一个*p++之后存在顺序点因而在第二个*p++求值之前已经做完一次自增。
- 完整表达式结束处包括表达式语句(如赋值a=b;),返回语句if、switch、while、do-while语句的控制表达式,for语句的3个表达式
- 函数调用时的函数入口点。函数实参的求值順序未指定但数序点意味着这些实参求值的副作用在进入函数时都已经完成。表达式f(i++) + g(j++) + h(k++)调用f(), g(), h()的顺序未指定,i, j, k的自增顺序也未指定函数調用f(a,b,c)的实参列表不是逗号运算符,a, b, and c的求值顺序未指定
- 函数返回时,在返回值已经复制到调用上下文(仅C++标准指出这一顺序点)
- 初始化的結束。例如声明int a = 5;中的对5求值之后。
- 在声明序列的每个声明(declarator)之间例如,int x = a++, y = a++的两次a++求值之间注意,此例不是逗号运算符