国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

查看: 3051|回復: 0
打印 上一主題 下一主題

聊聊for循環

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

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

for循環是C語言中最基本的循環結構了,其典型應用是在已知循環次數時,進行的一系列循環操作。基本語法格式舉例如下:

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

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

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

另外,每個表達式的位置也并非只能放置一個表達式,要知道,C語言中有一種逗號表達式,用逗號將多個表達式分隔開,在處理上,當做一個表達式來對待,最右邊的表達式運算結果即為整個表達式的值。基于此理論,上面的階乘運算可以改寫為下面的格式:

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

這樣寫有什么好處呢?當然絕不僅僅是為了扮酷,在結構上,能夠將一個整體運算緊密的結合在一起,可以最大限度的減小程序修改時遺漏等失誤。Ctrl+C和Ctrl+V應該在寫程序及修改程序中經常用到吧,如果寫成這樣,在復制過程中想丟掉語句都難。

第二個表達式可以寫成逗號表達式的形式嗎?當然也可以,不過我現在先不舉例,待會會和一些注意事項一起說明。現在我們先把for循環的結構剖析一下,看看for循環究竟是怎樣運行的。

首先是第一個表達式,這個表達式雖然是在for循環的循環表達式中出現的,但卻不在循環體內,其實是循環體前面緊鄰循環體的一個表達式,這也是上面兩個寫法效果相同的原因。畢竟它本身就是在循環體外面的,前一個程序只是光明正大的給寫在了外面。為了證實這一點,我們來看一下for循環的匯編代碼(不同編譯器可能會有所不同,這里是在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是跳轉指令,在跳轉指令下面是循環體。循環體代碼如下:

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

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

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

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

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

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

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

本版積分規則

關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久久久久久99精品免费 | 亚洲成人网在线播放 | 久久久窝窝午夜精品 | 亚洲高清视频在线观看 | 中文字幕五月天 | 免费国产va在线观看视频 | 日韩精品一区二区三区在线观看 | 午夜黄色一级片 | 白色强人粤语版在线观看港剧网 | 成年女人在线观看片免费视频 | 欧美三级视频在线 | 成人国产三级在线播放 | 九一视频在线观看 | 97性视频| 日本精品视频一区二区 | 91麻豆精品国产91久久久久 | 精品日本三级在线观看视频 | 国产成人综合网在线播放 | 天美麻豆国产传媒免费视频 | 亚洲一二三四 | 色老头成人免费视频天天综合 | 亚洲成人在线免费观看 | 欧美曰逼 | 欧美视频免费在线观看 | 免费在线视频a | 亚洲三页 | 激情六月婷婷 | 日韩视频亚洲 | 自拍视频在线观看 | 2021精品综合久久久久 | 日韩视频在线播放 | 456亚洲人成影视在线观看 | 家庭教师姐姐 | 午夜免费观看福利片一区二区三区 | 日韩成人影视 | 国产青青草视频 | 丁香六月在线 | 欧美一区日韩精品 | 99热2| 日韩在线二区 | 国产精品18p|