C语言提供了两种非常有用的运算符就是增一和减一运算符
增一运算符是用两个加号来表示的
增一运算的作用使参与运算的值增加一个单位
增一和减一运算符都是一元运算,只需要一个操作数
它既可以作为前缀运算符,也可以作为后缀运算符
当增一和减一运算符都作为前缀运算符的时候,就是把增一和减一运算符放在它的操作数的前面。
而后缀 则把运算符放在操作数的后面
++n 增一运算符的作用,将变量的值加一之后,再重新写回到变量中去
减一运算符的作用就是,将。。。。。。。。。。。。。。。。
由于增一和减一等价的操作中还包括赋值运算
++n → n = n + 1
而赋值运算的左值不允许是表达式的,因此增一和减一它的操作数只能是变量,不能是表达式
由于它是读出这个变量的值加一之后,在重新写回到这个变量中去,因此,增一运算符也称为自增运算符
减一运算符也称为自减运算符
顾名思义自增运算符就是将变量自身的值加一。
无论作为前缀还是后缀,
它等价的操作都是一样的
增一减一为什么还要区分前缀和后缀呢?
如果将自增和自减运算,放到另外的一个表达式中的话,那么前缀和后缀就有区分理论,
作为前缀时:
先对n的值进行增1/减1,然后在去使用变量n的值
m=++n
将增一运算,放到这样的一个赋值表达式中;构成这样的一个赋值表达式语句;那么在这种情况下,这个运算符是前缀和后罪有区分的
它是先对n的值进行增1运算,然后在去使用变量n的值
m=++n;→ n=n=1; m=n
所谓之后去使用变量的值,意味着把自增运算符拿掉然后在看它是一个什么样子的操作
在这里,把自增运算符拿掉以后,就是将n的值赋值给m,
pintf("%d",++n)→n=n+1
先执行对n的自增运算,因为这里是前缀运算符,所以先对n加一运算,
然后拿掉++自增运算,在看它是一条什么样子的语句
printf("%d",n)向屏幕输出n的值
但是这里向屏幕输出n的值,是经过n加一之后n的值。
如果单从执行结果上来看,那么图上两条语句是等价的
用增一减一运算生成的代码比相应的两条语句执行速度快的多
也就是增一减一生成的目标代码的执行效率更高
作为后缀运算
后缀运算就是先去使用n的值,然后在对n的值进行增1操作
m=n++;
对变量n执行增1操作是后执行
先把自增运算符拿掉
m=n; 是一条赋值语句
n=n+1;在进行操作
后缀运算符表示对n执行的加一操作是后执行的
printf("%d",n++);
printf("%d",n);先使用n的值,在使用n的值,之后,在加一的操作
n=n+1;
前缀与后缀对变量和表达式的影响
m=++n-2;
赋值运算符右侧表达式包括两个,一个是自增一个是算术
自增运算符是一元运算符,是高于算术运算符的
因此它是相当于m=(++n)-2;
(++n)是前缀运算符,因此它相当于,先对n=n+1;
然后拿掉自增运算符m=n-2;
m=n+±2;
后缀看图
printf("%d",-n++)
这个例子中包含了两个一元运算符
而一元运算符,优先级相同,
因此,就需要根据运算符的结合性来去分析它究竟是如何来执行的
由于在C语言中,一元运算符都是右结合的,因此它相当于是把
printf("%d",-(n++))→
n=n+1;错误
printf("%d",-n)意味着++是前缀运算符
但本表达式是后缀运算符
所以不等价
printf("%d",-(n++))→
printf("%d",-n)
n=n+1; 正确
为什么将n++扩起来了,却不执行n++呢?
奥秘;我们把n++扩起来究竟代表了什么含义?这里吧n++扩起来,它只表示n++的运算对象是n,而不是-n
如果是-n的话,它表示不是右结合的了。printf("%d",(-n)++);
而是左结合的了。是从左往右计算了
正是因为它是右结合,所以要将n++扩起来;就是从右往左
如果它是一个左结合就会出现,就会-n=-n+1
相当于对-n执行加1的操作
而前面我们讲过,自增运算符只能对变量进行运算
也就是自增运算符的运算对象只能是变量,而不能是一个表达式。
-n是一个表达式,那么将表达式放在赋值运算符的左侧,这个是违反C语言的语法规则
C规定:赋值运算符的左侧一定是一个变量,不能是一个表达式。
因为我们不可能将一个表达式,赋值给另外的一个表达式,
我们只能是赋值给一个变量,赋值操作只是一个写操作,也就是把这个表达式的值,写入到变量中去、
但我们无法写入到一个表达式中去,因此它是违法的。
因此它不是左结合的printf("%d"(-n)++)
将n++扩起来,就是表示,自增运算符的运算对象是n,而不是-n,但是将n++扩起来,并不代表,将n++运算一定是先执行,它到底是先执行还是后执行,要看自增运算符是一个前缀还是后缀
如果它是一个前缀运算符,一定先执行
后缀 后执行
之所以扩起来,只是代表这个(n++)操作符的运算对象是n而不是-n