1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        while(1) 和 for(;;)有什么區(qū)別?

        共 2026字,需瀏覽 5分鐘

         ·

        2021-12-23 01:55

        作者 |?strongerHuang

        微信公眾號(hào) |?嵌入式專欄

        有讀者問(wèn)題了類似這樣的問(wèn)題:while(1) 和 for(;;)它們不都是無(wú)限循環(huán)嗎,作用應(yīng)該一樣啊,它們到底有什么區(qū)別?


        要回答這個(gè)問(wèn)題,其實(shí)你各自編寫(xiě)一段while(1) 和 for(;;)的代碼,編譯對(duì)比一下代碼大小和匯編文件,你就大概知道了。


        while(1)和for(;;)語(yǔ)法表達(dá)

        這里先說(shuō)一下while(1)和for(;;)語(yǔ)法表達(dá)式。

        1.while語(yǔ)法表達(dá)
        while( 表達(dá)式 ){  語(yǔ)句}

        其中:

        • 表達(dá)式:是循環(huán)條件

        • 語(yǔ)句:為循環(huán)體。


        while語(yǔ)句的語(yǔ)義是:計(jì)算表達(dá)式的值,當(dāng)值為真(非0)時(shí), 執(zhí)行循環(huán)體語(yǔ)句。其執(zhí)行過(guò)程可用下圖表示:

        2.for語(yǔ)法表達(dá)
        for(表達(dá)式1; 表達(dá)式2; 表達(dá)式3) {  語(yǔ)句}

        它的執(zhí)行過(guò)程如下:

        1.先求解表達(dá)式1


        2.求解表達(dá)式2

        若其值為真(非0),則執(zhí)行for語(yǔ)句中指定的內(nèi)嵌語(yǔ)句,然后執(zhí)行下面第3)步;

        若其值為假(0),則結(jié)束循環(huán),轉(zhuǎn)到第5)步。


        3.求解表達(dá)式3


        4.轉(zhuǎn)回上面第2)步繼續(xù)執(zhí)行。


        5.循環(huán)結(jié)束,執(zhí)行for語(yǔ)句下面的一個(gè)語(yǔ)句。


        執(zhí)行過(guò)程可用下圖表示:


        while(1)和for(;;)異同點(diǎn)

        這里先說(shuō)一下結(jié)論,然后再驗(yàn)證驗(yàn)證結(jié)論。

        1.相同點(diǎn)
        作用和效果都一樣:都是實(shí)現(xiàn)無(wú)限循環(huán)的功能。

        2.不同點(diǎn)
        while(1):其中括號(hào)里面是一個(gè)條件,程序會(huì)判斷真假。而括號(hào)里面的“1”永遠(yuǎn)是一個(gè)“真值”。

        其中,每一次循環(huán),編譯器都要判斷常量1是不是等于零。

        for(;;):這兩個(gè);;空語(yǔ)句,編譯器一般會(huì)優(yōu)化掉的,直接進(jìn)入死循環(huán)。

        根據(jù)上面的描述,你可能會(huì)覺(jué)得:while(1) 比 for(;;) 要做更多事,匯編代碼更多,代碼量也更大。

        但事實(shí)是這樣嗎?下面驗(yàn)證一下。

        驗(yàn)證while(1)和for(;;)差異

        我們編寫(xiě)分別兩個(gè)文件for.c和while.c,然后分別生成匯編代碼,看下情況。

        1.源代碼
        while.c
        // filename: while.cint main(int argc, char const *argv[]){    while(1)    {}
        return 0;}

        for.c
        // filename: for.cint main(int argc, char const *argv[]){    for(;;)    {}
        return 0;}

        2.生成匯編
        我們這里使用gcc編譯器生成匯編,執(zhí)行命令如下:
        gcc -S -o while.s while.cgcc -S -o for.s for.c

        while匯編代碼:
        ; filename: whiles  .file  "while.c"  .text  .globl  main  .type  main, @functionmain:.LFB0:  .cfi_startproc  pushq  %rbp  .cfi_def_cfa_offset 16  .cfi_offset 6, -16  movq  %rsp, %rbp  .cfi_def_cfa_register 6  movl  %edi, -4(%rbp)  movq  %rsi, -16(%rbp).L2:  jmp  .L2  .cfi_endproc.LFE0:  .size  main, .-main  .ident  "GCC: (GNU) 9.3.0"  .section  .note.GNU-stack,"",@progbits

        for匯編代碼:
        ; filename: for.s  .file  "for.c"  .text  .globl  main  .type  main, @functionmain:.LFB0:  .cfi_startproc  pushq  %rbp  .cfi_def_cfa_offset 16  .cfi_offset 6, -16  movq  %rsp, %rbp  .cfi_def_cfa_register 6  movl  %edi, -4(%rbp)  movq  %rsi, -16(%rbp).L2:  jmp  .L2  .cfi_endproc.LFE0:  .size  main, .-main  .ident  "GCC: (GNU) 9.3.0"  .section  .note.GNU-stack,"",@progbits

        你會(huì)發(fā)現(xiàn),除了文件名不同,其余都相同。

        當(dāng)然,這里額外說(shuō)一下,不同代碼、不同編譯器,以及不同優(yōu)化等級(jí),可能最終結(jié)果有所差異。

        --- EOF ---

        瀏覽 40
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            亚洲女人天堂视频 | 欧美一区二区三区五月天婷婷 | 爽好大快要尿了 | 久久人人爽人人人人片 | jlzz国产丝袜18老师女人 | 欧美一级婬片免费视频日日木 | 凹凸69堂国产成人精品 | 少妇饥渴偷公三次 | 欧美一级AAAAAA片免费蜜桃 | ass疯狂少妇pics |