ip地址在c语言中长度是多少_c语言中(++i)+(++i)+(++i)究竟等于多少?
闲来无事学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)究竟等于多少?相关推荐
- IP地址的三种表示格式及在Socket编程中的应用
转自:http://blog.csdn.net/hguisu/article/details/7449955 使用TCP/IP协议进行网络应用开发的朋友首先要面对的就是对IP地址信息的处理.IP地址其 ...
- IP地址的三种表示格式 及 在Socket编程中的应用
关于windows中的INADDR_ANY这个宏 头文件winsock.h中定义#define INADDR_ANY (u_long)0x00000000 它是用于多IP机器 ...
- c语言设置输出字符大小_C语言中常用的几个头文件及库函数
点击上方"C语言中文社区",选择"设为星标★" 技术干货第一时间送达! 来源:https://www.jb51.net/article/124594.htm 这 ...
- 找出一批正整数中的最大偶数_c语言求一批正整数的奇数和-求奇数和输入一批正整数c语言程序-找出一批正整数中最大的偶数c语言...
#include "stdio.h" int main() { int a[10],i,j,k; printf("输入10个整数:\n"); for(i=k=0 ...
- c语言prime函数怎么用_C语言教程_v20201106
编程基础 1.1 通俗地理解什么是编程语言 1.2 C语言究竟是一门怎样的语言? 1.6 初中毕业能学会编程吗? 1.7 C和C++到底有什么关系? 1.8 学了 C 语 ...
- c语言string函数的用法_C语言基础| 指针和函数
点击蓝字关注我们 指针和函数 栈帧:当函数被调用时,系统会在stack空间上申请一块内存,用来给函数提供空间,存储形参和局部变量(定义在函数内部的变量). 当函数调用结束时,这块内存空间会被自动释放( ...
- c程序设计语言 qsort,【程序设计基础_C语言】北理工的恶龙(附qsort范例)
[程序设计基础_C语言]北理工的恶龙(附qsort实例) 北理工的恶龙(附qsort实例) 背景:最近,北理工出现了一只恶龙,它长着很多 头,而且还会吐火,它将会把北理工烧成废墟, 于是,校长下令召集 ...
- c语言代码大全表解释_C语言常用错误代码释义大全,值得收藏!
对于刚学编程,刚接触C++的新手来说,编译运行报错是最头疼的一件事,爆出一堆英文,英语差一点的又不知道什么意思,所以也不知道如何去改,在此,我给大家传一份常见错误中英文对照表及简单解释,希望可以帮到大 ...
- vc 运行c语言步骤,第1章_C语言概述(vc++环境如何运行c语言程序)[精选].ppt
第1章_C语言概述(vc环境如何运行c语言程序)[精选] C语言程序设计 授课对象:电子商务06 时间安排: 理论课(1-9周): 星期一 5-6节 9407D 星期三 5-6节 9410D 实验课( ...
- c语言局部变量存在什么区_C语言程序设计变量运用指南 C语言局部变量的存储方式和生存期...
动态存储方式与静态存储方式 从变量的作用域(即从空间)的角度来观察,变量可以分为全局变量和局部变量.从变量值存在的时间(即生存期)来观察,有的变量在程序运行的整个过程都是存在的,而有的变量则是在调用其 ...
最新文章
- 《http权威指南》读书笔记 二
- mysql数据库表的基本操作
- http与https的区别,http 1.0与1.1的区别
- java数据类型之间的转化
- java简单的死锁检测(转载线下代码)
- 软件推荐-有道超级计算器
- 文件系统缓存dirty_ratio与dirty_background_ratio两个参数区别
- Java web后端6 java Bean EL表达式
- 解决:idea - maven project 中 jar 报红线
- php mysql 反斜杠_MySQL中如何插入反斜杠,反斜杠被吃掉,反斜杠转义(转)
- 【实操手册】如何把一场直播录制下来?
- 【监控】使用 Grafana、collectd 和 InfluxDB 打造现代监控系统
- 移位 c语言一个变量存储两个值,【杭州C 培训】C语言中基础小问题总结
- 当当图书项目首页实现
- python中文分词的主要方法
- linux 防火墙reject,CentOS 防火墙配置与REJECT导致没有生效问题
- [图论]最大流问题(Maximum flow)的定义
- Filter过滤器讲解
- 网易云音乐常用API浅析
- 漫画解读:车规芯片为何比普通芯片贵?跟普通芯片有什么差异?
热门文章
- C# const, readonly, static readonly
- 提纲挈领webrtc音频处理算法之写在前面的话
- C语言中strstr函数
- OpenCV Python 直方图
- ASP.NET读取XML文件
- 使用升级版的 Bootstrap typeahead v1.2.2
- [BUG记录]java.lang.IllegalArgumentException: The observer is null.异常解决方案
- java日志分级概要
- MyCat分片规则之自定义范围分片
- Navicat for MySQL触发器更新和插入操作