C語言循環結構
注意,請認真學習完《C程序設計(第五版)》第五章後再閱讀本文會有更大的收獲。
通過之前的學習我們知道程序所處理的是數據,而日常的數據都存儲在數據庫裡,一般它們有着相同的數據結構,在批量處理這些數據的時候通常就會使用循環控制語句。對于輸入數據類型和結構一緻、處理邏輯一緻的程序一般都可以采用循環控制語句來實現,不僅簡化了代碼結構,還使得後續代碼擴展和維護更方便。
while循環書本上講了while和do...while兩種循環結構,通過了解其特性得知其主要差别在于do...while不管條件滿足與否都會先執行一次循環體,所以,在日後的使用中不推薦使用do...while循環,因為常規的邏輯基本上都是隻有滿足條件才去執行,即使遇到可以使用do...while的情形,我們也用while去代替它以使整個項目的代碼風格保持一緻。
for循環
for循環
書本最開始舉例求和就向我們展示了for循環,這次終于見識了廬山真面目。在使用過程中我們不要省略掉任何一個表達式,一味地追求簡潔反而會“适得其反”。
嵌套不僅僅是循環之間可以互相嵌套,我們上一課學習的if語句也可以參與進來和while、for等一起形成複雜的多重嵌套程序,一般在循環體内常用if語句去做判斷處理。
嵌套循環
跳出循環常規跳出
這裡指的是代碼執行循環體直到不能滿足循環條件的時候,程序會自動跳出循環,比如我們求1~100的和,當數字自增到101的時候會自然跳出循環。
手動跳出
在循環體處理數據時有差别對待,或者循環體執行過程中産生了不符合預期的結果,這時候我們要手動跳出循環——coutinue或者break。
情形1,在處理數據1~100的循環體中,要求對偶數進行一些計算,而忽略奇數。那我們判斷當前數是奇數的時候就可以用continue來跳出當前的循環而繼續進行下一次循環。
情形2,在處理數據1~100的循環體中,要求找出5個可以被3整除的數字即可。那當我們找到第五個滿足條件的數字之後就不用再執行下去了,此時用break來跳出整個循環。
死循環如果一個循環控制程序裡不設置終止條件,或者循環體有問題導緻不能觸發跳出循環的語句,這時候就是我們通常說的“死循環”。
我們在編程的過程中要避免死循環的出現,除非是寫那些需要一直運行着的腳本程序。
實戰編程輸入兩個正整數m和n,求其最大公約數和最小公倍數。
這是一道數學題,先搞清楚兩個及其以上正整數最大公約數和最小公倍數的定義,然後再來想清楚算法去解題。
最大公約數:從m和n中取出任意一個數字比如m,然後從1開始找m的約數x,如果x也是n的約數則x就是m和n的公約數;直到循環數自增到m,整個循環過程中找出符合條件的公約數會越來越大,那麼最後一次賦值給x的公約數則為最大公約數(因為每次賦值會覆蓋上一次的公約數的值)。這裡無論m和n誰大誰小都不會影響程序的結果,如果提前判斷大小關系,從小數來找公約數會減少循環次數,感興趣的同學可以自己改進程序。
最小公倍數:先找到m和n中的最小數,然後從1開始相乘找最小數的倍數,一旦同時能被m和n整除,那麼這個數就是m和n的最小公倍數。
void fun4() {
int m, n;
printf("輸入兩個正整數:\n");
scanf_s("%d%d", &m, &n);
int x = 1;
for (int i = 1; i <= m; i ) {
if (m % i == 0 && n % i == 0) {
x = i;
}
}
printf("最大公約數是:%d\n", x);
int min = m < n ? m : n;
int i = 1;
while (1) {
int num = min * i;
if (num % m == 0 && num % n == 0) {
printf("最小公倍數是:%d\n", num);
break;
}
i ;
}
}
PS:找最大公約數還有一種算法:先找到m和n之中的最小數,然後從大到小循環這個最小數去找公約數,找到的第一個公約數就是最大公約數,這個算法感興趣的去嘗試一下吧~
找最小公倍數也可以用另外一種算法:先找到m和n之中的最大數,然後讓最大數自增加,注意不是相乘,這樣去判斷能否都被m和n整除,一旦符合條件即可得到最小公倍數。
求之值,其中a是一個數字,n表示a的位數,n由鍵盤輸入。例如:2 22 222 2222 22222 (此時n=5)
這道題的思路分為二:一是循環構建n個數,二是每個數再循環生成,要用到嵌套循環。構建數字的算法是解題核心,參考下面代碼:
void fun5() {
int a = 3, n;
printf("輸入n:\n");
scanf_s("%d", &n);
int sum = 0;
for (int i = 1; i <= n; i ) {
int num = 0;
for (int j = 1; j <= i; j ) {
num = a * pow(10, j - 1);
}
printf("%d\t", num);
sum = num;
}
printf("\n");
printf("sum is %d\n", sum);
}
本題和“水仙花數”有相似之處,可以用三層循環構造三位數去判斷是否符合“水仙花數”。
PS:代碼裡用到pow()函數要在文件開頭包含math.h頭文件:#include <math.h>。
一個數如果恰好等于它的各個因子之和,這個數就稱為“完數”。例如,6的因子為1,2,3,而6=1 2 3,因此6是“完數”。編程找出1000之内的所有完數,并按下面的格式輸出其因子:
6 its factors are 1,2,3
這個題目還是要用循環嵌套來解,先循環1000以内數字,然後再循環分解每個數字的因子,參考如下:
void fun9() {
for (int num = 1; num < 1000; num ) {
int tmp_sum = 0;
for (int i = 1; i < num; i ) {
if (num % i == 0) {
tmp_sum = i;
}
}
if (num == tmp_sum) {
printf("%d 是完數\n", num);
}
}
}
PS:本示例代碼并沒有輸出各個因子,在判斷是完數之後再重複上面的那個循環去輸出因子,同學們自己練習吧~
猴子吃桃問題:猴子第一天摘下若幹個桃子,當即吃了一半,還不過瘾,又多吃了一個。第二天早上又将第一天剩下的桃子吃掉一半,又多吃了一個。以後每天早上都吃了前一天剩下的一半零一個。到第 10 天早上想再吃時,發現隻剩下一個桃子了。編寫程序求猴子第一天摘了多少個桃子。
又是數學問題。本題的關鍵是算清楚一個公式,前一天的桃子數記為before,後一天的桃子數記為after,根據題目得到after = before / 2 - 1,進而推導出 before = (after 1) * 2,這樣我們從最後一天開始往前推導就得出了第一天的桃子數量了,代碼參考:
void fun12() {
int before, after = 1, days = 10;
for (int i = 1; i < days; i )
{
before = 2 * (after 1);
after = before;
printf("第%d天的桃子數:%d\n", days - i, before);
}
printf("總共桃子個數:%d\n", before);
}
初學者對循環體可能有下面幾個迷惑點:
很多人一開始會糾結從0開始還是從1開始,在99終止還是在100終止這兩點,其實隻要你寫代碼去運行看結果,多改幾遍代碼看看不同的條件對應什麼結果,自然就能熟練掌握了。跳出循環的時機主要看算法的設計是怎樣的,不同的題目有多重算法,解題的時候也要多去嘗試,多鍛煉自己的解題思路,為今後學習算法做好鋪墊。
強調一點,由于初學者沒有實際的項目經驗,所以書本上的練習題幾乎都是以數學題的形式出現,這個就考驗我們的數學功底了,這點在之前的文章中有提過。
學完if語句和本節課的循環語句,就可以寫出來很多程序了,大家有空多多練習吧,現階段還是算法到編程轉換的關鍵時期,趁機會多鍛煉自己的編程思維~
往期文章一起學《C程序設計》第四課——if語句、switch語句及實戰練習
一起學《C程序設計》第三課——數據結構、運算符、表達式和語句
一起學《C程序設計》第二課——算法
一起學《C程序設計》第一課——C語言概述和學習前的準備、意識
C程序設計(譚浩強)——第五版和第三版對比
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!