设为首页 加入收藏

TOP

关于不同编译器下C语言中自加(++)运算符的解释(二)
2014-11-24 00:36:41 来源: 作者: 【 】 浏览:86
Tags:关于 不同 编译器 言中 运算 符的 解释
:a=37;b=9!!!其实主要是前两个++的理解:(++b)+(++b),要注意,++b并不是4,人们往往以为第一个是4,然后4+5,计算机并没有额外存储4这个数字,那么在都到下一个(++b)后,b=5,然后运算b+b=10,懂了吧?人类往往把4额外存储起来,就像这个式子表达的一样c=++b;a=c+(++b)+(++b);上面我已经做了演示。


下面我们看下TC的编译器理解:


TC下面执行b=3;a=(++b)+(++b)+(++b)是多少呢?答案是18;


可以看出TC编译器对此的解释是先全部做完自加运算得出最后的b值,然后再做加法运算,

本人尝试将TC反汇编一下,但是代码的可读性非常差。找了半天找到了关键部分:

[html] * Referenced by a CALL at Address:
|:0001.011A
|
:0001.01FA 55 push bp *把基址压倒堆栈
:0001.01FB 8BEC mov bp, sp *把堆栈偏移地址放入bp
:0001.01FD 56 push si
:0001.01FE 57 push di
:0001.01FF BF0100 mov di, 0001 a
:0001.0202 BE0300 mov si, 0003 b
:0001.0205 46 inc si ++b
:0001.0206 46 inc si ++b
:0001.0207 46 inc si ++b
:0001.0208 8BFE mov di, si
:0001.020A 03FE add di, si
:0001.020C 03FE add di, si
:0001.020E 56 push si
:0001.020F 57 push di
:0001.0210 B89401 mov ax, 0194
:0001.0213 50 push ax
:0001.0214 E8B206 call 08C9
:0001.0217 83C406 add sp, 0006
:0001.021A E85410 call 1271
:0001.021D 33C0 xor ax, ax
:0001.021F EB00 jmp 0221
* Referenced by a CALL at Address:
|:0001.011A
|
:0001.01FA 55 push bp *把基址压倒堆栈
:0001.01FB 8BEC mov bp, sp *把堆栈偏移地址放入bp
:0001.01FD 56 push si
:0001.01FE 57 push di
:0001.01FF BF0100 mov di, 0001 a
:0001.0202 BE0300 mov si, 0003 b
:0001.0205 46 inc si ++b
:0001.0206 46 inc si ++b
:0001.0207 46 inc si ++b
:0001.0208 8BFE mov di, si
:0001.020A 03FE add di, si
:0001.020C 03FE add di, si
:0001.020E 56 push si
:0001.020F 57 push di
:0001.0210 B89401 mov ax, 0194
:0001.0213 50 push ax
:0001.0214 E8B206 call 08C9
:0001.0217 83C406 add sp, 0006
:0001.021A E85410 call 1271
:0001.021D 33C0 xor ax, ax
:0001.021F EB00 jmp 0221

看到没有,si寄存器保存了b=3变量值,并且先自增了三次,变为6了,然后做了两次加法,和存在di中。这个与GCC编译器解释不同吧,哎,大约6年没用汇编了,看了很生疏,很多都忘了,抽空看看把。


总结:

编写代码,效率要考虑,但是要避免有歧义,费解的表达方式,程序还有个可读性要求,毕竟你写的代码以后要维护。

对于自加这种运算,要注意使用条件,有时你确实少写了那么一点代码,提高了那么一丁点的效率;但是往往会带来意想不到的错误。而且问题是不同编译器会做优化,所以实际执行顺序与你理解的可能并不一样。不过想必也没有人会在生产环境中写这样的代码。这篇文章也只是从汇编的角度来阐释了处理流程,我看到有些文章是从运算符结合和优先顺序来解释的,其实本质上是编译器的选择过程。

我试图能讲的很深入,发现很多东西都还给老师了,惭愧,哎,抽空复习复习。

拙文一篇,仅做抛砖引玉。

摘自 DesignLab

首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C:链表的操作(二),如何打印一.. 下一篇c字符串函数总结

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: