i++和++i的区别

i++和++i的区别

概念意思

  1. i++:先取值后自加

  2. ++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操作,效率低了一些.

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值