再一次的蛋疼“a++”和“++a”
一般来说讨论这种问题都是无聊+蛋疼的事情~
但是在日常开发中,总是会因为这个不可避免~
在代码书中或课堂上我们都知道++a和a++在作为一个单独语句使用时没有区别,即相当于a=a+1; 而作为语句的一部分时,如a=++a; 和a=a++; ++a先执行加1操作,再执行赋值操作(因++在前),而a++是先执行赋值操作,再执行加1操作(因++在后)。但这种论述未将其中更深的运行机制讲出来,尤其是在if或whale等判断语句中,下面对其进行探讨:
作为单独语句存在,如下面的两段代码:
//代码1
ant a=0;
if(a++){…}
//代码2
ant a=0;
if(++a){…}
ant a=0;
if(++a){…}
上面的条件判断代码虽然是以单独语句出现,但编译器将其等价于a++(或++a)>0,故在第一段代码中先执行a>0判定,再执行a++,因此条件体里的代码不被执行;而在第二段代码中先执行a=a+1,再执行a>0,因此条件里代码会被执行。
2.作为语句的一部分存在,如下面的一段代码:
ant a=4,b=5;
if((a++=b++)!=4){…}
上面的代码中括号()的优先级比!=的优先级高,但编译器仍然将++运算符最后执行。即先执行赋值语句a=b,然后判定(a=3)!=4成立,最后执行a++和b++,接下去执行条件体里代码。
综上可知当a++作为单独条件语句进行判定时,即使没有显示地声明与0的比较,编译器仍将加上与0的比较;当a++作为复合语句使用时,不管++是否在优先级更高的运算符中,++仍然最后才执行,即在当前所在语句操作执行之后。
按照C语言的标准解释来说,这就是表达式求值和副作用的效果.
C语言里面任何东西都是为这两点服务的.
int a=10;
a++;表达式值是10,副作用是a变量自增1
++a;表达式值是12,副作用仍然是变量自增1。
个人感觉求值和副作用分开来分析和记忆要比合起来更不容易让人迷惑。
不过像这种
if((a++=b++)!=4){…}
有两点错误:
1、a++和++a的表达式值都是右值,不能给其赋值。
2、a在同一个序列点内被修改了两次,属于未定义行为。