651-C语言的运算符和表达式(2)

前置或者后置++ --运算符

++ --是单目运算符,因为它只需要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编译器执行的前置++和后置++的操作如下:
在这里插入图片描述
都是返回的是临时量(立即数字,是没有内存的,是常量数字,不能作为左值)。
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林林林ZEYU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值