最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

第 9 講:循環(huán)的嵌套

2021-08-30 16:23 作者:SunnieShine  | 我要投稿

嵌套?

什么是嵌套(Nest)?嵌套是 C 語言和其它眾多編程語言里的一個(gè)重要的語法術(shù)語,它表示執(zhí)行的控制流語句(if、switchwhile、do-whilefor 語句統(tǒng)稱控制流語句,它們控制著整個(gè)程序的執(zhí)行流程:是條件判斷來走不同分支,還是反復(fù)執(zhí)行相同的執(zhí)行語句)的內(nèi)部繼續(xù)使用這些控制流語句的寫法。比如前文介紹的 if 內(nèi)還有 if 的情況:

比如這個(gè)寫法格式里的 j 的結(jié)果是 3,它先走了 i == 2 這個(gè) if 條件的 else 部分,然后發(fā)現(xiàn)它也不滿足 i < 2 的情況,所以它最終走了 i < 2 這個(gè) if 條件里的 else 部分,獲得了 j = 3 的賦值。

很有意思的是,循環(huán)也是可以嵌套使用的。正因?yàn)槿绱?,循環(huán)和條件判斷的各種語句才會產(chǎn)生各種不同的組合模式,產(chǎn)生不同的代碼書寫技巧,比如枚舉法(Enumeration)。不過,我們先要介紹,代碼到底是怎么運(yùn)算執(zhí)行嵌套循環(huán)的。


實(shí)例:質(zhì)數(shù)的判斷

最好理解的、最基礎(chǔ)的例子就是求質(zhì)數(shù)了。

質(zhì)數(shù)的定義是,在把一個(gè)大于等于 2 的整數(shù)分解為多個(gè)正整數(shù)的乘積時(shí),如果只能分解為 1 × 自己 的話,這個(gè)數(shù)就是質(zhì)數(shù)(也稱素?cái)?shù),Prime),一般常見的質(zhì)數(shù)有 2、3、5、7、11、13、17、19 等。

現(xiàn)在我們嘗試輸出所有 100 以內(nèi)的所有質(zhì)數(shù)。我們的代碼怎么寫呢?


先實(shí)現(xiàn)判別質(zhì)數(shù)的功能

首先,我們嘗試用爆破的方式,對一個(gè)整數(shù)嘗試進(jìn)行挨個(gè)數(shù)字的試除。如果這個(gè)整數(shù)無法被整除掉,說明它只能被 1 整除掉,故這個(gè)數(shù)肯定就是質(zhì)數(shù)了。比如,我們要計(jì)算 17 是否是質(zhì)數(shù)(即使我們背了表,知道它是質(zhì)數(shù)),邏輯大致就是從 2 開始,一直計(jì)算到 16(17 除以 17 顯然等于 1,所以這個(gè)除法已經(jīng)沒有意義了,所以我們只要求計(jì)算到 16 即可),讓 17 挨個(gè)去除以這個(gè)數(shù),如果每一次除法得到的結(jié)果都不能被整除,說明這個(gè)數(shù)肯定就是質(zhì)數(shù)了):

我們來大致看下邏輯。首先,我們?yōu)樾枰玫降臈l件進(jìn)行變量的聲明(定義),然后設(shè)置一個(gè)結(jié)果量 isPrime,來表示它是否是質(zhì)數(shù)(1 表示這個(gè)數(shù)是質(zhì)數(shù),0 表示這個(gè)數(shù)不是質(zhì)數(shù))。

然后考慮 while 循環(huán)里的內(nèi)容。我們肯定要讓 n 從 2 計(jì)算到 digit - 1,然后嘗試記錄每一次試除得到的余數(shù) remainder。記錄余數(shù)有什么用呢?在 C 語言里,判斷一個(gè)數(shù)是否能被整除,用的方法是得到余數(shù),看余數(shù)是否為 0。比如 12 % 2 的結(jié)果為 0,因?yàn)?12 是可以整除 2 的。

如果 remainder 為 0,說明被整除了。在除法過程里得到完全整除的現(xiàn)象,就標(biāo)志著這個(gè)數(shù)肯定就不是質(zhì)數(shù)了。比如在計(jì)算 15(digit 是 15)的時(shí)候,如果 n 此時(shí)是 3,那么 remainder 就是 0 了,所以 digit 不是質(zhì)數(shù),我們需要將結(jié)果量 isPrime 改為 0。 標(biāo)志著這個(gè)數(shù)肯定不是質(zhì)數(shù)了。

不過,如果在得到 remainder 為 0 的情況時(shí),就標(biāo)志著這個(gè)數(shù)不是質(zhì)數(shù)了。既然它已經(jīng)肯定不是質(zhì)數(shù)了,所以此時(shí)就不必再往下算了,所以我們此時(shí)想要嘗試跳到循環(huán)外面,繼續(xù)執(zhí)行下面的語句。不過,我們目前還沒有講解這一點(diǎn),所以我們先不考慮這一點(diǎn)的優(yōu)化。哪怕后面再次遇到余數(shù) 0 的情況,因?yàn)檠h(huán)里只有對 isPrime = 0 的賦值,所以局面完全不可能被反轉(zhuǎn),即 isPrime 完全不可能被重新改為 1,所以大不了多幾次被賦值為 0 罷了。

另外,循環(huán)條件其實(shí)也可以優(yōu)化,不過為了邏輯的清晰易懂,所以這里我們不提及任何有關(guān)優(yōu)化的部分。

當(dāng)試除循環(huán)執(zhí)行完畢,發(fā)現(xiàn) isPrime 還是為初始賦值的情況 1,就說明在我們試除的循環(huán)里完全沒有遇到余數(shù)為 0,即被整除的情況。所以這個(gè)數(shù) digit 應(yīng)為質(zhì)數(shù),所以我們認(rèn)為這個(gè)數(shù)就是質(zhì)數(shù),輸出 digit 是一個(gè)質(zhì)數(shù)的信息,反之輸出不是質(zhì)數(shù)的信息。

所以,前面給出的算法邏輯是完整的、正確的。


為遍歷 2 到 100 寫一層循環(huán)

那么,我們既然做出了這個(gè)模塊,那么,要想輸出所有質(zhì)數(shù)的信息,只需要把最后 isPrime 的判斷的 if 條件去掉 else 部分,然后把輸出語句改為直接輸出這個(gè)數(shù)字,最后再在整個(gè)執(zhí)行流程的外部加入一個(gè) while 循環(huán),計(jì)算 2 到 100 的所有數(shù)字即可。

可以看到,Old code 代碼塊里面的這一大堆代碼都是前文用過的代碼,被我原封不動(dòng)地復(fù)制過來了。我們把 digit 從 17 改為了 2。因?yàn)槲覀冞@個(gè)題目的真正目的是為了遍歷前面 100 個(gè)正整數(shù),而 0 和 1 既不是質(zhì)數(shù)也不是合數(shù),所以我們直接從 2 開始計(jì)算。

然后,程序執(zhí)行到 digit <= 100 時(shí),顯然滿足條件,所以進(jìn)入到循環(huán)里。然后為 nisPrime 進(jìn)行初始化的賦值。然后進(jìn)入之前的判斷質(zhì)數(shù)的代碼塊里。如果 digit 是質(zhì)數(shù),則肯定會進(jìn)入到上述代碼第 23 行代碼里,并輸出這個(gè)數(shù)字,然后緊跟一個(gè)空格,為了保證后面可能會輸出的數(shù)字會和這個(gè)當(dāng)前數(shù)字之間有一個(gè)空格的分隔。

然后,最后到達(dá)第 27 行代碼,digit 會增大一個(gè)單位,比如 digit 從 2 變?yōu)?3,整個(gè)循環(huán)執(zhí)行完畢。接著,倒回 digit <= 100 的條件處判斷。顯然,它還是滿足要求,所以重新進(jìn)入到循環(huán)里。然后又一次對 nisPrime 執(zhí)行初始化的賦值。

實(shí)際上,從這里就可以看出來,把這兩句初始賦值寫在循環(huán)里的原因。因?yàn)槊恳粋€(gè)不同的數(shù)字判斷是否是質(zhì)數(shù)的時(shí)候,都采用的是 nisPrime 兩個(gè)變量。重新賦值初始值是為了避免計(jì)算過后,更改了這兩個(gè)變量的數(shù)值,而我們沒有重新修正數(shù)值,就會影響到程序執(zhí)行,并出現(xiàn)沒有達(dá)到預(yù)期結(jié)果的 bug。

可以看到,這一則實(shí)例用到了兩層 while 循環(huán),外層 while 循環(huán)表示的意思是,想要從 2 計(jì)算到 100,把每一個(gè)數(shù)字都判斷一遍,它們是否是質(zhì)數(shù);而內(nèi)層的 while 循環(huán)在這里表示的意思是,嘗試把外層循環(huán)得到的當(dāng)前需要計(jì)算的數(shù)字 digit 去逐個(gè)用 2 開始試除,看看這個(gè)數(shù)是否能被內(nèi)層循環(huán)得到的這個(gè)數(shù)字所除盡。


其它循環(huán)的嵌套

for 循環(huán)的嵌套

while 循環(huán)的嵌套還是很簡單的,不過 for 循環(huán)嵌套的理解難點(diǎn)就在于它的小括號的三個(gè)部分的執(zhí)行順序。只要你不要忘了 for 循環(huán)的執(zhí)行順序:初始值、條件、循環(huán)體、增量、條件、循環(huán)體、增量、條件、循環(huán)體、增量……

例如上述邏輯,就可以改寫為如下的代碼格式:

實(shí)際上,改寫代碼后,代碼量更少了,邏輯也清晰了,只是代碼可能會稍微難理解一些。但只要你每一步按部就班地來,就不會出現(xiàn)邏輯執(zhí)行的順序錯(cuò)誤。


do-while 循環(huán)的嵌套

用得最少的就是 do-while 循環(huán)了,所以它的嵌套很多時(shí)候,雖然簡單,但難理解。不過一般我們都用不上,所以這里就隨便舉了個(gè)例,然后改寫成 do-while 循環(huán)書寫。

這個(gè)例子的輸出結(jié)果是

%5Cbegin%7Bmatrix%7D%0A%5Ctext%7B*%7D%5C%5C%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%5Cend%7Bmatrix%7D

循環(huán)語句的大括號省略

if 語句一樣,當(dāng)執(zhí)行循環(huán)的語句部分只有一句話的時(shí)候,我們可以去掉大括號不寫,比如:

它等價(jià)于

當(dāng)然,一個(gè)大括號也被視為一句話,所以如果 for 循環(huán)嵌套了例如 if 和大括號,或者 if-else 語句的話,這種形式也可以不要外層的大括號。

可以簡寫為

只要你覺得看起來?xiàng)l理清晰的時(shí)候,就可以這么書寫。


編碼技巧:枚舉法

枚舉法就是采用大量循環(huán)的嵌套,來枚舉出每一個(gè)循環(huán)的執(zhí)行邏輯的一種情況,然后挨個(gè)判斷條件是否滿足的邏輯。這種邏輯雖然很暴力,但枚舉出的所有情況保證了程序執(zhí)行的正確性。

想必很多人聽說過水仙花數(shù)字,它是一個(gè)三位數(shù),每一個(gè)位置的數(shù)字的三次方的和,等于它自己的數(shù)字。我們既然找不到解決方式,就干脆枚舉每一個(gè)情況,讓每一個(gè)變量表示這個(gè)數(shù)的每一個(gè)位置,大不了用三個(gè)變量 a、bc 表示百位、十位和個(gè)位。不過要注意,a 作為百位數(shù),是不可能為 0 的,否則它就不是一個(gè)合理的三位數(shù)了。

我相信,這樣的書寫模式一定會讓你對多重循環(huán)有一個(gè)更好的認(rèn)知:首先進(jìn)入 a = 1 的初始值賦值,然后顯然滿足條件,進(jìn)入 b = 0 的初始賦值,顯然滿足條件,所以進(jìn)入最內(nèi)層的循環(huán),c = 0 的初始值和條件。

然后全部滿足,所以我們開始整合這個(gè)整數(shù),把每一個(gè)整數(shù)合并起來變?yōu)橐粋€(gè)整數(shù)。然后嘗試對這三個(gè)數(shù)字 abc 執(zhí)行三次方計(jì)算再求和。如果它等于 digit,便滿足條件,所以此時(shí)就算滿足了水仙花數(shù)的要求,輸出它即可。否則,我們就計(jì)算下一次循環(huán)。注意,此時(shí)循環(huán)還在最內(nèi)層,所以執(zhí)行完畢這一次循環(huán)的時(shí)候,應(yīng)該走增量 c++ 的這個(gè)部分,此時(shí) c 表示的個(gè)位變?yōu)?1。然后再判斷條件 c <= 9。滿足條件,進(jìn)入循環(huán),再一次判斷條件是否滿足。

直到 c 計(jì)算到 9 的時(shí)候,增量使得 c 變?yōu)?10,此時(shí)條件不滿足。于是整個(gè)最內(nèi)層的 for 循環(huán)執(zhí)行完畢,發(fā)現(xiàn)它被包含在 b 計(jì)算的循環(huán)的這坨循環(huán)里,而這坨循環(huán)里只有關(guān)于 c 變量的循環(huán)一個(gè)部分,所以這便意味著 b 循環(huán)執(zhí)行完一次操作,此時(shí) b 才會增大一個(gè)單位(進(jìn)入 b++ 增量,使之變?yōu)?1)。然后再次進(jìn)入 c = 0 的初始賦值處。

如果用人為的邏輯理解的話,就是把它們?nèi)齻€(gè)整理為 100、101、102、103、……、109、110、111、……、999 的順序執(zhí)行每一個(gè)數(shù)字。

大致邏輯如下:

一些練習(xí)

嵌套循環(huán)還需要多多練習(xí)和鞏固,因?yàn)樗雌饋砗唵?,?shí)際上每一步執(zhí)行起來還是費(fèi)工夫的。所以我們來一些練習(xí),希望你們能夠明白和看懂它們的執(zhí)行。


方陣

將會輸出一個(gè)星星矩陣:

%5Cbegin%7Bmatrix%7D%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%0A%5Cend%7Bmatrix%7D

左上三角

將會是一個(gè)左上三角:

%5Cbegin%7Bmatrix%7D%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%5Ctext%7B*%7D%0A%5Cend%7Bmatrix%7D

左下三角

將會是一個(gè)左下三角:

%5Cbegin%7Bmatrix%7D%0A%5Ctext%7B*%7D%20%26%5C%5C%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%0A%5Cend%7Bmatrix%7D

右上三角

將會是一個(gè)右上三角:

%5Cbegin%7Bmatrix%7D%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%26%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%26%20%26%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%26%20%26%20%26%20%26%20%5Ctext%7B*%7D%0A%5Cend%7Bmatrix%7D

九九乘法表

這樣便會輸出一個(gè)九九乘法表:

菱形

最難的就是這個(gè)例子了。我們嘗試輸出一個(gè)菱形圖案。

將會得到一個(gè)菱形圖案:

%5Cbegin%7Bmatrix%7D%0A%26%20%26%20%26%20%26%20%5Ctext%7B*%7D%5C%5C%0A%26%20%26%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%26%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%5C%5C%0A%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%26%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%26%20%26%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%20%26%20%5Ctext%7B*%7D%5C%5C%0A%26%20%26%20%26%20%26%20%5Ctext%7B*%7D%0A%5Cend%7Bmatrix%7D

第 9 講:循環(huán)的嵌套的評論 (共 條)

分享到微博請遵守國家法律
体育| 黄龙县| 广平县| 顺义区| 财经| 抚松县| 若尔盖县| 贵南县| 霸州市| 齐齐哈尔市| 永平县| 灵台县| 泌阳县| 三明市| 读书| 正镶白旗| 滕州市| 华池县| 荃湾区| 云林县| 五峰| 翁源县| 宜宾县| 绵竹市| 祁门县| 遂川县| 遵义市| 湘阴县| 咸丰县| 保康县| 孟津县| 芜湖县| 烟台市| 台州市| 塘沽区| 柘城县| 徐汇区| 诏安县| 日照市| 高雄市| 吴桥县|