a+=1和a=a+1 的疑惑?

guixuhui2 2011-03-27 03:45:37
a+=1和a=a+1 为什么前者a求值一次,而后者求值两次?
...全文
1057 38 打赏 收藏 转发到动态 举报
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
jialejiahi 2011-03-28
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 guujiang 的回复:]

引用 3 楼 errno 的回复:
首先你要知道,a在作为赋值语句的左值或者右值时意义不同:作为左值时,其意义为变量的地址,a=1就是将符号a代表的内存空间存入“1”这个量;而作为右值的时候,它就直接作为我们习惯用的1来用。
总结起来,当a作为左值时代表存放的内存空间地址,右值作为数值的代名词(本例子中)。

第一个表达式中,左值a作为一个地址,+=将a内存内的值直接+1操作。

第……
[/Quote]
内存可以直接作为目的操作数,只是不允许源操作数和目的操作数都为内存。
guixuhui2 2011-03-28
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 jialejiahi 的回复:]
在旧的编译器中这是有差别的,现在编译器的优化都做的很好,实际上这两句产生的可执行代码是相同的。
先前的编译器a = a + 1为什么求值两次呢?
这里的“求值”意思是对内存的操作次数
a = a + 1的执行顺序是:
1:从内存取出a的值存入寄存器(假设名字为eax)
2:将寄存器eax中的值加1
3:将eax中的值存如变量a所在的内存

a += 1 则是将内存中值直接加一。
……
[/Quote]
按照21楼的说法,“求值”的意思应该是对寄存器的操作次数吧!那么“求值”的意思是什么?请楼下解答!
guixuhui2 2011-03-28
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 zhao4zhong1 的回复:]
VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编并单步执行一遍不就啥都明白了吗。
(Linux或Unix下应该也可以在用GDB调试时,看每句C对应的汇编。)
[/Quote]
你能把相应的代码贴出来给大家看看吗!?
w1a9n8g912 2011-03-28
  • 打赏
  • 举报
回复
a += 1 等于ADD (寄存器) (立即数)
a = a + 1 等于ADD (寄存器1) (立即数)
MOV (寄存器2) (寄存器1)
luocheng891019 2011-03-28
  • 打赏
  • 举报
回复
2楼和3路正解···
w1a9n8g912 2011-03-28
  • 打赏
  • 举报
回复
前者快,后者慢。
huihuipeng 2011-03-28
  • 打赏
  • 举报
回复
打个比方,变量a相当于一个杯子,a+=1就相当于在这个杯子里边直接倒了一升水(直接计算);
a=a+1就相当于在一个杯子里边倒了一升后(计算操作);然后再向另一个杯子里边倒入(赋值操作);
结果都一样,但在效率上第一种要优于第二种
fabulous 2011-03-28
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 delphiwcdj 的回复:]
引用 3 楼 errno 的回复:

首先你要知道,a在作为赋值语句的左值或者右值时意义不同:作为左值时,其意义为变量的地址,a=1就是将符号a代表的内存空间存入“1”这个量;而作为右值的时候,它就直接作为我们习惯用的1来用。
总结起来,当a作为左值时代表存放的内存空间地址,右值作为数值的代名词(本例子中)。

第一个表达式中,左值a作为一个地址,+=将a内存内的值直接+1操作。

……
[/Quote]+++
ctrigger 2011-03-28
  • 打赏
  • 举报
回复
正解!!!
[Quote=引用 3 楼 errno 的回复:]

首先你要知道,a在作为赋值语句的左值或者右值时意义不同:作为左值时,其意义为变量的地址,a=1就是将符号a代表的内存空间存入“1”这个量;而作为右值的时候,它就直接作为我们习惯用的1来用。
总结起来,当a作为左值时代表存放的内存空间地址,右值作为数值的代名词(本例子中)。

第一个表达式中,左值a作为一个地址,+=将a内存内的值直接+1操作。

第二个表达式中,首先计算a+1,然后作为……
[/Quote]
xjmlj2010 2011-03-28
  • 打赏
  • 举报
回复
两个都一样呀
赵4老师 2011-03-28
  • 打赏
  • 举报
回复
VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编并单步执行一遍不就啥都明白了吗。
(Linux或Unix下应该也可以在用GDB调试时,看每句C对应的汇编。)
l396634084 2011-03-28
  • 打赏
  • 举报
回复
如此这般,结分...
AnYidan 2011-03-28
  • 打赏
  • 举报
回复
各种说法,楼主采用哪种?
GuuJiang 2011-03-28
  • 打赏
  • 举报
回复
sorry,发出去才意识到一直想成a++和a+=1的区别了,事实上a+=b和a=a+b在编译时应该是完全等价的吧(不管b是多少,当然1可能是个特例,可以优化为inc),算做是个语法糖
GuuJiang 2011-03-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 errno 的回复:]
首先你要知道,a在作为赋值语句的左值或者右值时意义不同:作为左值时,其意义为变量的地址,a=1就是将符号a代表的内存空间存入“1”这个量;而作为右值的时候,它就直接作为我们习惯用的1来用。
总结起来,当a作为左值时代表存放的内存空间地址,右值作为数值的代名词(本例子中)。

第一个表达式中,左值a作为一个地址,+=将a内存内的值直接+1操作。

第二个表达式中,首先计算a+1,然后作为一……
[/Quote]

这么多人都说3L正解,有个疑问,真的存在“内存内的值直接+1”这种操作吗?
当然3L的意思是对的,不过一定要深究起来的话应该是所有的操作都是在寄存器中进行的吧,区别是,a+=1这个属于原地操作,编译时极有可能是对应inc指令,而a=a+1需要进行add(计算a+1),mov(保存临时结果),mov(赋值回a)等操作,当然相信现代的编译器应该都会把a=a+1优化为a+=1的吧
3L的总体意思是对的,“内存直接+1”是个小瑕疵
小枫 2011-03-28
  • 打赏
  • 举报
回复
7楼,我同意7楼的说法
wizard_tiger 2011-03-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 errno 的回复:]

首先你要知道,a在作为赋值语句的左值或者右值时意义不同:作为左值时,其意义为变量的地址,a=1就是将符号a代表的内存空间存入“1”这个量;而作为右值的时候,它就直接作为我们习惯用的1来用。
总结起来,当a作为左值时代表存放的内存空间地址,右值作为数值的代名词(本例子中)。

第一个表达式中,左值a作为一个地址,+=将a内存内的值直接+1操作。

第二个表达式中,首先计算a+1,然后作为……
[/Quote]
正解!
漁_夫 2011-03-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 errno 的回复:]

首先你要知道,a在作为赋值语句的左值或者右值时意义不同:作为左值时,其意义为变量的地址,a=1就是将符号a代表的内存空间存入“1”这个量;而作为右值的时候,它就直接作为我们习惯用的1来用。
总结起来,当a作为左值时代表存放的内存空间地址,右值作为数值的代名词(本例子中)。

第一个表达式中,左值a作为一个地址,+=将a内存内的值直接+1操作。

第二个表达式中,首先计算a+1,然后作为……
[/Quote]
支持
sghdls 2011-03-28
  • 打赏
  • 举报
回复


+= 是复合运算符
xzjxylophone 2011-03-28
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 zhao4zhong1 的回复:]

VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编并单步执行一遍不就啥都明白了吗。
(Linux或Unix下应该也可以在用GDB调试时,看每句C对应的汇编。)
[/Quote]

好多 这种问题, 此人都是用以上的文字 来回复的~~~~
加载更多回复(14)

70,014

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧