i++和++i的区别
概念意思
-
i++:先取值后自加
-
++i:先自加后取值
汇编代码生成分析
在汇编层面看这两个语句的区别,可以知道具体的实现细节
code 1 for i++
#include
void main()
{
int index = 0;
printf("index1:%d \r\n", index++);
printf("index2:%d \r\n", index);
}
code 2 for ++i
#include
void main()
{
int index = 0;
printf("index1:%d \r\n", ++index);
printf("index2:%d \r\n", index);
}
使用gcc -S生成对应的汇编代码
code 1 生成编译成可执行文件out,在通过objdump生成反汇编
gcc code1.c -o out
objdump -S -d out > 1.ttt
cat 1.ttt
找到i++的代码
void main()
{
40051d: 55 push %rbp
40051e: 48 89 e5 mov %rsp,%rbp
400521: 48 83 ec 10 sub $0x10,%rsp
int index = 0;
400525: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
printf("index1:%d \r\n", index++);
40052c: 8b 45 fc mov -0x4(%rbp),%eax
40052f: 8d 50 01 lea 0x1(%rax),%edx
400532: 89 55 fc mov %edx,-0x4(%rbp)
400535: 89 c6 mov %eax,%esi
400537: bf f0 05 40 00 mov $0x4005f0,%edi
40053c: b8 00 00 00 00 mov $0x0,%eax
400541: e8 ba fe ff ff callq 400400
printf("index2:%d \r\n", index);
400546: 8b 45 fc mov -0x4(%rbp),%eax
400549: 89 c6 mov %eax,%esi
40054b: bf fd 05 40 00 mov $0x4005fd,%edi
400550: b8 00 00 00 00 mov $0x0,%eax
400555: e8 a6 fe ff ff callq 400400
}
这里可以看到,movl $0x0,-0x4(%rbp)表示index = 0
index ++在汇编层面需要以下几条指令
mov -0x4(%rbp),%eax
lea 0x1(%rax),%edx
mov %edx,-0x4(%rbp)
读取index的值用于printf
保存index到临时变量edx,再edx自增1,
存储edx到index
code 2 生成编译成可执行文件out,在通过objdump生成反汇编
gcc code1.c -o out
objdump -S -d out > 2.ttt
cat 2.ttt
找到++i的代码
void main()
{
40051d: 55 push %rbp
40051e: 48 89 e5 mov %rsp,%rbp
400521: 48 83 ec 10 sub $0x10,%rsp
int index = 0;
400525: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
printf("index1:%d \r\n", ++index);
40052c: 83 45 fc 01 addl $0x1,-0x4(%rbp)
400530: 8b 45 fc mov -0x4(%rbp),%eax
400533: 89 c6 mov %eax,%esi
400535: bf f0 05 40 00 mov $0x4005f0,%edi
40053a: b8 00 00 00 00 mov $0x0,%eax
40053f: e8 bc fe ff ff callq 400400
printf("index2:%d \r\n", index);
400544: 8b 45 fc mov -0x4(%rbp),%eax
400547: 89 c6 mov %eax,%esi
400549: bf fd 05 40 00 mov $0x4005fd,%edi
40054e: b8 00 00 00 00 mov $0x0,%eax
400553: e8 a8 fe ff ff callq 400400
}
这里可以看到,
index变量初始化为0语句都是一样的,movl $0x0,-0x4(%rbp)
++index 在汇编层面需要以下几条指令
addl $0x1,-0x4(%rbp)
mov -0x4(%rbp),%eax
把index变量先自增
把index传给eax用于print
总结
从两个汇编代码可以得到一个结论
++i比i++要高效,因为i++要先把自己的值保存到寄存器后在自增,最后在去赋值,对比与++i操作,效率低了一些.