i=1,为什么 (++i)+(++i)=6?
生活随笔
收集整理的這篇文章主要介紹了
i=1,为什么 (++i)+(++i)=6?
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
源碼
#include "stdio.h"int main(void) {int i = 1;printf("%d\n",(++i) +(++i));return 0; }執(zhí)行
weiqifa@bsp-ubuntu1804:~/c/undif$ gcc g.c && ./a.out 6 weiqifa@bsp-ubuntu1804:~/c/undif$為什么出現(xiàn)這個(gè)鬼現(xiàn)象?
原因很簡(jiǎn)單,C語言的法律里面沒有定義這條規(guī)格,這個(gè)屬于C語言的未定義行為,也就是擦邊球,什么是擦邊球呢?就是這些行為不是錯(cuò)誤的行為,法律沒有明確定義的,所以就是擦邊球。
它的執(zhí)行順序是這樣的
int i = 1; ++i ;//i = 2 ++i ;//i = 3 i + i ; //輸出6反匯編看看
weiqifa@bsp-ubuntu1804:~/c/undif$ gcc -S g.c weiqifa@bsp-ubuntu1804:~/c/undif$ cat g.s.file "g.c".text.p .rodata .LC0:.string "%d\n".text.globl main.type main, @function main: .LFB0:.cfi_startprocpushq %rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq %rsp, %rbp.cfi_def_cfa_register 6subq $16, %rspmovl $1, -4(%rbp)addl $1, -4(%rbp)addl $1, -4(%rbp)movl -4(%rbp), %eaxaddl %eax, %eaxmovl %eax, %esileaq .LC0(%rip), %rdimovl $0, %eaxcall printf@PLTmovl $0, %eaxleave.cfi_def_cfa 7, 8ret.cfi_endproc .LFE0:.size main, .-main.ident "GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0".p .note.GNU-stack,"",@progbits weiqifa@bsp-ubuntu1804:~/c/undif$ ls我們不用關(guān)注所有的代碼,分析下面幾行關(guān)鍵的
subq $16, %rsp movl $1, -4(%rbp) //相當(dāng)于 i = 1 addl $1, -4(%rbp) //相當(dāng)于 i +1 addl $1, -4(%rbp) //相當(dāng)于 i +1 movl -4(%rbp), %eax // 把rbp寄存器傳給eax寄存器 addl %eax, %eax //相當(dāng)于 i + i看完這個(gè)代碼后,應(yīng)該知道為啥輸出的是 6 了吧?
最后
我認(rèn)為一個(gè)是編譯器執(zhí)行順序的問題,反匯編無非就是搞清楚C的執(zhí)行順序,而且我認(rèn)為研究這個(gè)是有意義的,不過有意義不代表可以這樣寫代碼。
C本身是偏底層的東西,了解編譯的原理和過程是非常重要的。
但是了解也不能這樣瞎用,還是要遵守規(guī)則,要不然,這樣導(dǎo)致的bug估計(jì)要害死很多人。
推薦閱讀:
專輯|Linux文章匯總
專輯|程序人生
嵌入式Linux
微信掃描二維碼,關(guān)注我的公眾號(hào)
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的i=1,为什么 (++i)+(++i)=6?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js验证码代码
- 下一篇: 【ps小技巧】内容识别, 1分钟去掉图片