ip地址在c语言中长度是多少_c语言中(++i)+(++i)+(++i)究竟等于多少?

78dd4c176a9fc80b69e3eebe93c1695c.png
闲来无事学C语言,天才室友问我(++I)+(++I)+(++I)在C语言怎么解,结果Vb得出答案是22!我就按照自己思路给同学解释,先自增后加法末赋值,但是我还是错了。错在什么地方呢?但是去百度一看,Vscode配合其他编译器还有等于24的,草,这答案都不正确吗?
我于是在terminal里的clang编译器试了一下,太狗血了!
室友说这个等于21
于是我决定要自己研究一番。。。

CODE:

#include "stdio.h"

int main() {
	int i=3;
	printf("%d",(++i)+(++i)+(++i));
	return 0;;
}

I GOT TWO VALUE FOR ANSWER!!

GCC-7.4.0 COMPILER:

$: gcc 运算符和表达式.c && ./a.out
$:16

CLANG-8.1.0 COMPILER:

$: clang 运算符和表达式.c && ./a.out
$:15

so, I reversed code for analysis.

reversed assembly(AT&T format)

gcc compiler:

000000000000064a <main>:
 64a:	55                   	push   %rbp      /赋值?/
 64b:	48 89 e5             	mov    %rsp,%rbp   /rsp,rbp为堆栈地址?/
 64e:	48 83 ec 10          	sub    $0x10,%rsp  /值为16/
 652:	c7 45 fc 03 00 00 00 	movl   $0x3,-0x4(%rbp)   /把i=3长字节放在rbp堆栈/
 659:	83 45 fc 01          	addl   $0x1,-0x4(%rbp)   /i=i+1放入rbp堆栈/
 65d:	83 45 fc 01          	addl   $0x1,-0x4(%rbp)   /i=i+1放入rbp堆栈,此时i=5/
 661:	8b 45 fc             	mov    -0x4(%rbp),%eax   /把rbp短字节(i=5)堆栈值,移动到寄存器ax/
 64a:	55                   	push   %rbp               /赋值?/
 64b:	48 89 e5             	mov    %rsp,%rbp          /rsp,rbp为堆栈地址?/
 64e:	48 83 ec 10          	sub    $0x10,%rsp         /值为16/
 652:	c7 45 fc 03 00 00 00 	movl   $0x3,-0x4(%rbp)    /把i=3长字节放在rbp堆栈/
 659:	83 45 fc 01          	addl   $0x1,-0x4(%rbp)    /i=i+1放入rbp堆栈/
 65d:	83 45 fc 01          	addl   $0x1,-0x4(%rbp)    /i=i+1放入rbp堆栈,此时i=5/
 661:	8b 45 fc             	mov    -0x4(%rbp),%eax    /把rbp短字节(i=5)堆栈值,移动到寄存器ax/
 664:	8d 14 00             	lea    (%rax,%rax,1),%edx /寄存器ax与寄存器ax相加放到寄存器dx/ /dx=10/
 667:	83 45 fc 01          	addl   $0x1,-0x4(%rbp)    /i=i+1=6放入rbp堆栈/
 66b:	8b 45 fc             	mov    -0x4(%rbp),%eax    /把结果i=6移动到寄存器ax/
 66e:	01 d0                	add    %edx,%eax          /把寄存器dx与寄存器ax相加,也就是10+6/
 670:	89 c6                	mov    %eax,%esi          /把16移动到寄存器si/
 672:	48 8d 3d 9b 00 00 00 	lea    0x9b(%rip),%rdi        # 714 <_IO_stdin_used+0x4>   /我也没看懂/   
 679:	b8 00 00 00 00       	mov    $0x0,%eax          /寄存器ax赋值/
 67e:	e8 9d fe ff ff       	callq  520 <printf@plt>   /调用fun函数printf/
 683:	b8 00 00 00 00       	mov    $0x0,%eax          /寄存器ax赋值/
 688:	c9                   	leaveq 
 689:	c3                   	retq 
 68a:	66 0f 1f 44 00 00    	nopw   0x0(%rax,%rax,1)  //   
可以看出,先自增两次,相加,再自增,再相加,后赋值。 gcc是不是不符合规范?他并不像书上说的,自增比加号的优先级高。

clang compiler:

0000000000400500 <main>:
  400500:	55                   	push   %rbp          /赋值?/
  400500:	55                   	push   %rbp               /赋值?/
  400501:	48 89 e5             	mov    %rsp,%rbp    
  400504:	48 83 ec 10          	sub    $0x10,%rsp
  400508:	48 bf e4 05 40 00 00 	movabs $0x4005e4,%rdi     
  40050f:	00 00 00 
  400512:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%rbp)     
  400519:	c7 45 f8 03 00 00 00 	movl   $0x3,-0x8(%rbp)
  400520:	8b 45 f8             	mov    -0x8(%rbp),%eax 
  400523:	83 c0 01             	add    $0x1,%eax          /寄存器ax +1,此时寄存器ax的i=4/
  400526:	89 45 f8             	mov    %eax,-0x8(%rbp)    /把i=i+1结果给rbp堆栈/
  400529:	8b 4d f8             	mov    -0x8(%rbp),%ecx    /把rbp堆栈赋值给寄存器cx,rbp堆栈的值为4/
  40052c:	83 c1 01             	add    $0x1,%ecx          /寄存器cx +1,此时寄存器cx的i=5/
  40052f:	89 4d f8             	mov    %ecx,-0x8(%rbp)    /寄存器cx值给rbp堆栈,rbp堆栈的值为5/
  400532:	01 c8                	add    %ecx,%eax          /寄存器ax与寄存器cx相加,4+5=9,寄存器ax为9/
  400534:	8b 4d f8             	mov    -0x8(%rbp),%ecx    /把rbp堆栈的值给寄存器cx,此时寄存器cx的值i=5/
  400537:	83 c1 01             	add    $0x1,%ecx          /寄存器cx +1,此时i=6/
  40053a:	89 4d f8             	mov    %ecx,-0x8(%rbp)    /寄存器cx值给rbp堆栈,rbp堆栈的值为6/
  40053d:	01 c8                	add    %ecx,%eax          /寄存器cx与寄存器ax相加,6+9=15/
  40053f:	89 c6                	mov    %eax,%esi          /寄存器ax值赋值到寄存器si/
  400541:	b0 00                	mov    $0x0,%al           /移动到寄存器al/
  400543:	e8 b8 fe ff ff       	callq  400400 <printf@plt>/调用fun函数printf/
  400548:	31 c9                	xor    %ecx,%ecx          /异或运算,cx与cx的值相同,结果为0/
  40054a:	89 45 f4             	mov    %eax,-0xc(%rbp)    /寄存器ax/
  40054d:	89 c8                	mov    %ecx,%eax          /寄存器cx的值给寄存器ax,结果是15/
  40054f:	48 83 c4 10          	add    $0x10,%rsp         /rsp堆栈为什么要填入10?/
  400553:	5d                   	pop    %rbp
  400554:	c3                   	retq   
  400555:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
  40055c:	00 00 00 
  40055f:	90                   	nop
我也得到clang的汇编结果,先自增,后相加,末赋值,严格按照了运算符规范!

#结论

经过这次的工作,我了解了编译器工作原理。 还有解决了室友所提问的问题。 我和他的答案都是正确的,只是编译器工作原理不同导致结果不一样。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值