BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #95007同步于 2017/4/5
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

一个C++中自增的小问题

zzt1993520
2017/4/5镜像同步17 回复
这样几句C++代码,我感觉很难受 ```CPP int a = 0; a = a++; cout<<a; //输出是1 ``` 如果单纯地从优先级考虑,先进行a++,这时,返回0,再赋值给a,a不应该是0吗? 求解答 --------------------------更新线-------------------------- 刚才忘了说明环境,发这个帖子的时候,我用的是VS2015,然后我用g++跑了一下,结果是0,所以,应该是如楼下所说的未定义行为。结贴啦! 我在底下附一下g++下的汇编代码,有兴趣的可以看一看: ```C .file "test.cpp" .def ___main; .scl 2; .type 32; .endef .section .rdata,"dr" LC0: .ascii "%d\0" .text .globl _main .def _main; .scl 2; .type 32; .endef _main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $32, %esp call ___main movl $0, 28(%esp) //把0放到esp+28的位置上 movl 28(%esp), %eax //把esp+28处的值放到eax寄存器里,此时eax里的值是0 leal 1(%eax), %edx //eax的值加一放到edx中,edx是1 movl %edx, 28(%esp) //edx的值放到esp+28处 movl %eax, 28(%esp) //eax的值放到esp+28中,那么还是0 movl 28(%esp), %eax //eax还是0啊 movl %eax, 4(%esp) //printf()函数的参数,从右到左入栈,eax,即0放到了esp+4的位置 movl $LC0, (%esp) //printf()的参数 call _printf //调用printf函数,输出是0,即寄存器eax的值 movl $0, %eax //程序的返回值 leave ret .ident "GCC: (tdm-1) 4.9.2" .def _printf; .scl 2; .type 32; .endef ```
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
jaegerstar机器人#1 · 2017/4/5
然后过了那一行以后a就被赋予1啦
zzt1993520机器人#2 · 2017/4/5
感谢回答,但还是有点不懂。。。 你的意思是,赋值其实没起作用吗?我知道a++之后其实a已经等于1了,只不过返回了它原来的值,但是接下来的赋值操作为什么没给a重新赋值呢? 【 在 jaegerstar 的大作中提到: 】 : 然后过了那一行以后a就被赋予1啦
Kxzuir机器人#3 · 2017/4/5
"在C语言中同一个表达式中如果改变一个变量的值两次,其结果是未定义的。" 不知道在C++中是不是这样,或许取决于编译器的实现。
amarantine机器人#4 · 2017/4/5
mov a a; inc a
zzt1993520机器人#5 · 2017/4/5
果然,C++里也应该是这样的了,刚才在vs和g++下试了一下,前者是1,后者是0。,此贴终结 【 在 Kxzuir 的大作中提到: 】 : "在C语言中同一个表达式中如果改变一个变量的值两次,其结果是未定义的。" : 不知道在C++中是不是这样,或许取决于编译器的实现。
a895981819机器人#6 · 2017/4/5
在顺序点之间有两次副作用操作,因此是为定义行为,全看编译器。 发自「贵邮」
duduscript机器人#7 · 2017/4/5
c++17规定了计算顺序 其他的都是未定义行为
MarkCV机器人#8 · 2017/4/6
C++中优先级的问题取决于编译器,这种问题本身就是毫无意义的,不要去瞎折腾编译器
eha机器人#9 · 2017/4/6
C++11还没完全学明白就要学C++17了[ema1]