闲来无事学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,%rsp400508:    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    %rbp400554:  c3                      retq   400555:  66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)40055c:  00 00 00 40055f:    90                      nop

我也得到clang的汇编结果,先自增,后相加,末赋值,严格按照了运算符规范!

#结论

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

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

  1. IP地址的三种表示格式及在Socket编程中的应用

    转自:http://blog.csdn.net/hguisu/article/details/7449955 使用TCP/IP协议进行网络应用开发的朋友首先要面对的就是对IP地址信息的处理.IP地址其 ...

  2. IP地址的三种表示格式 及 在Socket编程中的应用

    关于windows中的INADDR_ANY这个宏 头文件winsock.h中定义#define INADDR_ANY              (u_long)0x00000000 它是用于多IP机器 ...

  3. c语言设置输出字符大小_C语言中常用的几个头文件及库函数

    点击上方"C语言中文社区",选择"设为星标★" 技术干货第一时间送达! 来源:https://www.jb51.net/article/124594.htm 这 ...

  4. 找出一批正整数中的最大偶数_c语言求一批正整数的奇数和-求奇数和输入一批正整数c语言程序-找出一批正整数中最大的偶数c语言...

    #include "stdio.h" int main() { int a[10],i,j,k; printf("输入10个整数:\n"); for(i=k=0 ...

  5. c语言prime函数怎么用_C语言教程_v20201106

    编程基础 1.1    通俗地理解什么是编程语言 1.2    C语言究竟是一门怎样的语言? 1.6    初中毕业能学会编程吗? 1.7    C和C++到底有什么关系? 1.8    学了 C 语 ...

  6. c语言string函数的用法_C语言基础| 指针和函数

    点击蓝字关注我们 指针和函数 栈帧:当函数被调用时,系统会在stack空间上申请一块内存,用来给函数提供空间,存储形参和局部变量(定义在函数内部的变量). 当函数调用结束时,这块内存空间会被自动释放( ...

  7. c程序设计语言 qsort,【程序设计基础_C语言】北理工的恶龙(附qsort范例)

    [程序设计基础_C语言]北理工的恶龙(附qsort实例) 北理工的恶龙(附qsort实例) 背景:最近,北理工出现了一只恶龙,它长着很多 头,而且还会吐火,它将会把北理工烧成废墟, 于是,校长下令召集 ...

  8. c语言代码大全表解释_C语言常用错误代码释义大全,值得收藏!

    对于刚学编程,刚接触C++的新手来说,编译运行报错是最头疼的一件事,爆出一堆英文,英语差一点的又不知道什么意思,所以也不知道如何去改,在此,我给大家传一份常见错误中英文对照表及简单解释,希望可以帮到大 ...

  9. vc 运行c语言步骤,第1章_C语言概述(vc++环境如何运行c语言程序)[精选].ppt

    第1章_C语言概述(vc环境如何运行c语言程序)[精选] C语言程序设计 授课对象:电子商务06 时间安排: 理论课(1-9周): 星期一 5-6节 9407D 星期三 5-6节 9410D 实验课( ...

  10. c语言局部变量存在什么区_C语言程序设计变量运用指南 C语言局部变量的存储方式和生存期...

    动态存储方式与静态存储方式 从变量的作用域(即从空间)的角度来观察,变量可以分为全局变量和局部变量.从变量值存在的时间(即生存期)来观察,有的变量在程序运行的整个过程都是存在的,而有的变量则是在调用其 ...

最新文章

  1. 《http权威指南》读书笔记 二
  2. mysql数据库表的基本操作
  3. http与https的区别,http 1.0与1.1的区别
  4. java数据类型之间的转化
  5. java简单的死锁检测(转载线下代码)
  6. 软件推荐-有道超级计算器
  7. 文件系统缓存dirty_ratio与dirty_background_ratio两个参数区别
  8. Java web后端6 java Bean EL表达式
  9. 解决:idea - maven project 中 jar 报红线
  10. php mysql 反斜杠_MySQL中如何插入反斜杠,反斜杠被吃掉,反斜杠转义(转)
  11. 【实操手册】如何把一场直播录制下来?
  12. 【监控】使用 Grafana、collectd 和 InfluxDB 打造现代监控系统
  13. 移位 c语言一个变量存储两个值,【杭州C  培训】C语言中基础小问题总结
  14. 当当图书项目首页实现
  15. python中文分词的主要方法
  16. linux 防火墙reject,CentOS 防火墙配置与REJECT导致没有生效问题
  17. [图论]最大流问题(Maximum flow)的定义
  18. Filter过滤器讲解
  19. 网易云音乐常用API浅析
  20. 漫画解读:车规芯片为何比普通芯片贵?跟普通芯片有什么差异?

热门文章

  1. C# const, readonly, static readonly
  2. 提纲挈领webrtc音频处理算法之写在前面的话
  3. C语言中strstr函数
  4. OpenCV Python 直方图
  5. ASP.NET读取XML文件
  6. 使用升级版的 Bootstrap typeahead v1.2.2
  7. [BUG记录]java.lang.IllegalArgumentException: The observer is null.异常解决方案
  8. java日志分级概要
  9. MyCat分片规则之自定义范围分片
  10. Navicat for MySQL触发器更新和插入操作