前置或者后置++ --运算符
++ --是单目运算符,因为它只需要1个参数参与运算
后置的++
前置的++
我们转到反汇编看看:
如果把前置++和后置++单独写出来,在汇编指令上是一模一样的。
x86的指令,从右往左看,从a这个内存取出(双字)4字节,也就是取出a的值10,放在寄存器eax里面,然后add,让eax的值加个1,eax原来的值是a的值10,现在+1,变成11,然后move,把寄存器eax的11放回a的内存里面,就是把a改为11了。
现在我们依然看不出来前置++和后置++的区别。
如果把前置++和后置++单独写在一行,成为独立的表达式,是看不出来区别的。
但是,我们看下面代码,如果前置++和后置++是处在复杂较长的语句中:它们之间就有区别了!!!
什么时候算使用完了?
就是语句结束了–》
1、遇到分号;
2、逗号表达式的逗号,
3、条件表达式是问号?
然后执行++,–
我们看下面例子:
遇见逗号表达式的逗号,算结束,我们先求表达式1:a++,遇见逗号,语句结束,算出来a是11,然后算表达式2,b=a++,a先给b赋值,b=11,a遇见逗号了,使用完了,a=11+1=12,然后执行表达式3:a+b=12+11=23
遇见逗号也要去计算后置++的++操作哦!!!
我们再来看看
条件表达式:3个表达式,2个运算符合在一块,单拿出来不能用,必须包含冒号和问号
我们看下面例子:
?前面的表达式如果成立,为true,就返回?和:之间的表达式1的结果,如果?前面的表达式不成立,为false,就返回:后面的表达式2的结果
我们来计算下面这道题:
a和b的初始化值都是10,先计算关系表达式a>b还是先给a+1?因为这是后置++,所以先使用再++,在这里算的就是10>10,算完以后,遇到?,a+1=11,10不大于10,所以?前面的表达式是不成立的,是false,这个条件表达式返回的就是:后面的表达式2的结果了,执行a++这个表达式,a先使用,然后++,所以c=a=11,然后遇见;执行a++,a=12
C++的后置++
后置的++,- -进行赋值操作,或者放在=的左边当做左值来使用是不可以的!
我们把后置的++看作一个逗号表达式:
相当于是产生了一个临时量tmp=a,然后执行a=a+1,然后返回tmp
也就是说,这个a初始化是10,a++相当于是在寄存器记录了一下a原来的值10,然后a=a+1=11,然后返回临时量tmp=10,也就是寄存器中的一个常量数字,是不能给10赋给10 , 10是不能作为左值的
C++的前置++
我们把前置的++看作一个逗号表达式:
先执行a=a+1,然后把a返回回来
也就是说,前置的++或者–表达式本身就是有内存的变量本身。
所以肯定可以给a赋值,因为a有名字有内存,在栈上,可以作为左值!!!
a从10加到11,然后a又被10赋值,所以a最终=10
类似a+++++b到底该怎么分析(C++)
首先,我们的编译器里面,不管是C还是C++,根本没有5个加法运算符连在一起的运算符,所以,对于这样的表达式,编译器在试图理解它的时候,采用的是贪心算法来分解这个表达式,就是从左向右先拿出1个+号,认为是一个合法的运算符,因为有加号嘛,a+,然后再拿出一个+号,a++,也认为是一个合法的运算符,因为C/C++都有++构成的运算符,然后再拿出一个+号,a+++,这个就没有办法组成一个有效的运算符了,因为C/C++都没有+++这个运算符,这就不合法了,所以编译器就把它们分割成:
a++ +
所以,所谓的贪心算法就是从左向右来分解这个表达式,它的意思就是:从左向右,以一次能组成的最长的合法的运算符的方式进行表达式的分割。
所以,再拿出一个+号,就分割成:
a++ ++
然后再拿出一个+号,a++ +++,+++就不合法了,所以分割成:
a++ ++ +
所以对于编译器来说,它最终理解这个表达式是:
a++ ++ +b
所以实际上,它是在计算这个表达式:
()后面的这个++作用于的表达式是:a++,即后置的a++,但是后置的++是常量数字,是没有内存的,不能当做左值来使用的!!!相当于是执行10++这种操作,毫无意义!!!
给后置的++操作完然后再进行++
就是在给10++,毫无意义,所以这个表达式是错误的。
如果是下面这种写法就可以了:
因为这是我们主动加了空格,编译器就按照我们的方式进行了。
a++ + ++b
b和a的初始化都是10
前置的++先++再使用,++b,b=11
a++是后置的++,先使用再++,那就是10+11=21,然后执行a++,a=11
我们再来看下面这个例子:
这个表达式是错误的,
我们来分析一下:
为什么是错误的?
因为++或者- -是单目运算符,就是它要进行运算的参数只需要1个,而且它不像加减乘除, 它默认是由左向右运算的,所以,它是从右向左结合的,
相当于前面的那个++作用的表达式又是一个后置++,立即数字,没有内存,不能给10进行前置的++,所以这是一个错误的表达式!!!
下面这样写就是正确的:
现在括号后面的++作用的就是前置的++,返回的a是有内存有名字的。
先计算++a,a变为11,然后11+10=21,然后给a++,a=12
和- -是同理的。
C语言的++和- -
在C语言中,前置的++ - -和后置的++ - -都是不可以作为左值的。
在C编译器中,认为前置++也不是左值
C编译器执行的前置++和后置++的操作如下:
都是返回的是临时量(立即数字,是没有内存的,是常量数字,不能作为左值)。