色偷偷偷久久伊人大杳蕉,色爽交视频免费观看,欧美扒开腿做爽爽爽a片,欧美孕交alscan巨交xxx,日日碰狠狠躁久久躁蜜桃

x
x
查看: 3104|回復(fù): 0
打印 上一主題 下一主題

聊聊for循環(huán)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2011-4-29 07:57:08 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
關(guān)鍵詞: For , 循環(huán)
for循環(huán)是我最喜歡的循環(huán)結(jié)構(gòu)了,本來以為我對for循環(huán)已經(jīng)很了解了,但在最近是使用之中不斷的出問題,所以我又對for循環(huán)進(jìn)行了一次比較深入的“研究”,研究結(jié)果使我大吃一驚,不得不感嘆,C語言真的是高深莫測。

好了,感慨完了,讓我們從頭開始來聊一聊這個最熟悉但又最難以捉摸的for循環(huán)吧。

for循環(huán)是C語言中最基本的循環(huán)結(jié)構(gòu)了,其典型應(yīng)用是在已知循環(huán)次數(shù)時,進(jìn)行的一系列循環(huán)操作;菊Z法格式舉例如下:

for(i=0;i<=100;i++)

括號中有三個表達(dá)式,其中第一個表達(dá)式用來給循環(huán)計數(shù)器賦初值,第二個表達(dá)式用來判斷是否滿足循環(huán)條件,第三個表達(dá)式用來改變循環(huán)計數(shù)器的值。
當(dāng)然,這只是最基本的用法,這三個表達(dá)式并非只能針對同一個變量,甚至,并非每個都必須出現(xiàn),這只是在循環(huán)體的不同位置進(jìn)行運(yùn)算的三個普通表達(dá)式而已。例如下面,計算n的階乘,直到大于100為止:

a=1;
for(i=1;a<=100;i++) a*=i;

另外,每個表達(dá)式的位置也并非只能放置一個表達(dá)式,要知道,C語言中有一種逗號表達(dá)式,用逗號將多個表達(dá)式分隔開,在處理上,當(dāng)做一個表達(dá)式來對待,最右邊的表達(dá)式運(yùn)算結(jié)果即為整個表達(dá)式的值;诖死碚,上面的階乘運(yùn)算可以改寫為下面的格式:

for(a=1,i=1;a<=100;i++) a*=i;

這樣寫有什么好處呢?當(dāng)然絕不僅僅是為了扮酷,在結(jié)構(gòu)上,能夠?qū)⒁粋整體運(yùn)算緊密的結(jié)合在一起,可以最大限度的減小程序修改時遺漏等失誤。Ctrl+C和Ctrl+V應(yīng)該在寫程序及修改程序中經(jīng)常用到吧,如果寫成這樣,在復(fù)制過程中想丟掉語句都難。

第二個表達(dá)式可以寫成逗號表達(dá)式的形式嗎?當(dāng)然也可以,不過我現(xiàn)在先不舉例,待會會和一些注意事項一起說明,F(xiàn)在我們先把for循環(huán)的結(jié)構(gòu)剖析一下,看看for循環(huán)究竟是怎樣運(yùn)行的。

首先是第一個表達(dá)式,這個表達(dá)式雖然是在for循環(huán)的循環(huán)表達(dá)式中出現(xiàn)的,但卻不在循環(huán)體內(nèi),其實是循環(huán)體前面緊鄰循環(huán)體的一個表達(dá)式,這也是上面兩個寫法效果相同的原因。畢竟它本身就是在循環(huán)體外面的,前一個程序只是光明正大的給寫在了外面。為了證實這一點(diǎn),我們來看一下for循環(huán)的匯編代碼(不同編譯器可能會有所不同,這里是在Keil4.1下編譯的,編譯器版本是armcc 4.0.0.728,選擇的處理器是8962,因此編譯出來的匯編指令是ARM CortexM3的指令)。

第一種寫法:
     4: a=1;
0x000001A8 2101      MOVS     r1,#0x01
     5: for(i=1;a<=100;i++) a*=i;
0x000001AA 2201      MOVS     r2,#0x01
0x000001AC E001      B        0x000001B2
0x000001AE 4351      MULS     r1,r2,r1
0x000001B0 1C52      ADDS     r2,r2,#1
0x000001B2 2964      CMP      r1,#0x64
0x000001B4 DDFB      BLE      0x000001AE
     6: }

第二種寫法:
     4: for(a=1,i=1;a<=100;i++) a*=i;
0x000001A8 2101      MOVS     r1,#0x01
0x000001AA 2201      MOVS     r2,#0x01
0x000001AC E001      B        0x000001B2
0x000001AE 4351      MULS     r1,r2,r1
0x000001B0 1C52      ADDS     r2,r2,#1
0x000001B2 2964      CMP      r1,#0x64
0x000001B4 DDFB      BLE      0x000001AE
     5: }

可以看出,二者編譯出來的匯編代碼完全一樣。在這里,B是跳轉(zhuǎn)指令,在跳轉(zhuǎn)指令下面是循環(huán)體。循環(huán)體代碼如下:

0x000001AE 4351      MULS     r1,r2,r1
0x000001B0 1C52      ADDS     r2,r2,#1
0x000001B2 2964      CMP      r1,#0x64
0x000001B4 DDFB      BLE      0x000001AE

了解一些匯編的不難看出來(我也是在驗證這個for循環(huán)時看了一點(diǎn)ARM匯編,我參考的文檔是Cortex-M3 Technical Reference Manual),BLE是條件跳轉(zhuǎn),根據(jù)條件跳轉(zhuǎn)到前面的某一行語句上,循環(huán)的基本寫法。

C語言中對for循環(huán)的執(zhí)行過程描述如下:首先計算一次表達(dá)式1的值(參考格式:for(表達(dá)式1;表達(dá)式2;表達(dá)式3),再計算表達(dá)式2的值,如果表達(dá)式2的值為true,則執(zhí)行一次循環(huán)體,如果表達(dá)式2的值為false,則退出循環(huán)體。沒執(zhí)行完一次循環(huán)體后,計算表達(dá)式3的值,然后再計算表達(dá)式2的值,并根據(jù)表達(dá)式2的值決定是否繼續(xù)執(zhí)行循環(huán)體。

在這里表達(dá)式2需要在兩個位置計算,一是剛進(jìn)入循環(huán)時判斷第一次循環(huán)是否執(zhí)行,另外則是在每次執(zhí)行完循環(huán)時判斷是否進(jìn)行下一次循環(huán),一個位置是在整個循環(huán)體前,另一個位置是在表達(dá)式3之后。在編譯過程中,為了減小程序體積,表達(dá)式2只在表達(dá)式3之后計算。同時在循環(huán)體前增加一個無條件跳轉(zhuǎn)指令跳過整個循環(huán)體(包括表達(dá)式3)跳轉(zhuǎn)到循環(huán)的結(jié)尾來做第一次判斷。所以,for循環(huán)的執(zhí)行是從最后的指令開始執(zhí)行的。

總結(jié)一下,for循環(huán)中的三個表達(dá)式執(zhí)行方式如下:表達(dá)式1在整個循環(huán)體的前面(循環(huán)體外)執(zhí)行一次,表達(dá)式2為循環(huán)體的最后一組指令(可以有多個表達(dá)式組成,下同),表達(dá)式3為倒數(shù)第二組指令,在表達(dá)式2前面緊鄰表達(dá)式執(zhí)行。

注:關(guān)于循環(huán)體的定義,在C語言表達(dá)式中,for循環(huán)的三個表達(dá)式都不屬于循環(huán)體,但是假如以匯編的跳轉(zhuǎn)指令界定的話,表達(dá)式2和表達(dá)式3也應(yīng)該屬于循環(huán)體,畢竟它們也是以同樣的次數(shù)循環(huán)執(zhí)行的。以上只是為了說明我在文中使用的循環(huán)體名稱,很久不玩匯編了,對一些定義也都忘記了,所以也可能官方定義不同。

by  柳葉舟
您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號 | 京公網(wǎng)安備11010502021702
快速回復(fù) 返回頂部 返回列表