為什麼需要迴圈控制
迴圈結構或稱重複結構
幾乎每一種計算機高階語言都提供了迴圈控制,用來處理需要進行的重複操作
大多數的應用程式都會包含迴圈結構
迴圈結構和順序結構、選擇結構是結構化程式設計的3中基本結構,它們是各種複雜程式的基本構成單元。
用 while 語句實現迴圈
while 語句的一般形式:while (表示式) 語句
其中“語句”就是迴圈體。迴圈體只能是一個語句,可以是一個簡單的語句,還可以是複合語句(用花括號包起來的若干語句)
執行迴圈體的次數是由迴圈條件控制的,這個迴圈條件就是“表示式”,它也成為迴圈條件式。
當迴圈條件式的值為“真”(非0)時,就執行迴圈,否則就不執行迴圈語句
在執行 while 語句時,先檢查迴圈條件表示式的值,當為非0值(真)時,就執行 while 語句中的迴圈體語句;當表示式為0(假)時,不執行迴圈體語句
while 迴圈流程:
while迴圈的特點:先判斷條件表示式,後執行迴圈體語句
例:求1+2+3+...+100的值
//例:求1+2+3+...+100的值
#include <stdio.h>
int main(void)
{
int i = 1, sum = 0;
while (i < 101)
{
sum += i;
i++;
}
printf("%d\n", sum);
return 0;
}
在VS編譯器內會報C4996錯誤,解決見下文:(下同)
C4996 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. - EricsT - 部落格園 (cnblogs.com)
執行結果:
迴圈體如果包含一個以上的語句,應該用花括號括起來,作為複合語句出現。如果不加花括號則 while 語句的範圍只到 while 後面的第一個分號處。
迴圈體中應該有使迴圈趨向於結束的語句。
用 do...while 語句實現迴圈
do...while 語句的執行過程是:先執行迴圈體,然後再檢查條件是否成立,若成立則再執行迴圈體。
do...while 語句的特點是:先無條件的執行迴圈體,然後判斷迴圈條件是否成立
//do...while 語句的一般形式:
do
語句
while (表示式);
do...while 迴圈的流程:
先執行一次指定的迴圈體語句,然後判別表示式,當表示式的值為非零(真)時,返回重新執行迴圈體語句,如此反覆,直到表示式的值等於0(假)為止,此時迴圈結束
例:求1+2+3+...+100的值
//例:求1+2+3+...+100的值
#include <stdio.h>
int main(void)
{
int i = 1, sum = 0;
do
{
sum += i;
i++;
} while (i < 101);
printf("%d\n", sum);
return 0;
}
執行結果:
對同一個問題可以用 while 語句處理,也可以用 do...while 語句處理。do...while 結構可以轉換為 while 結構。
在一般情況下,用 while 語句和用 do...while 語句處理同一問題時,若二者的迴圈體部分是一致的,那麼結果也是一致的。但是如果 while 後面的表示式一開始就是為假(0值)時,兩種迴圈的結果是不同的,while 迴圈一次不進行,但是 do...while 迴圈會進行一次迴圈。
當 while 後面的表示式的第一次的值為“真”時,兩種迴圈得到的結果相同;否則,二者結果不相同(指二者具有相同的迴圈體的情況)
用 for 語句實現迴圈
for 語句更為靈活,不僅可以用於迴圈次數已經確定的情況,還可以用於迴圈次數不確定而只給出迴圈結束條件的情況,它完全可以代替 while 語句
//for語句的一般形式:
for (表示式1; 表示式2; 表示式3)
語句
3個表示式的主要作用:
- 表示式1:設定初始條件,只執行一次。可以為零個、一個或多個變數設定初值
- 表示式2:是迴圈條件表示式,用來判別是否繼續迴圈。在每次執行迴圈體前先執行此表示式,決定是否繼續執行迴圈
- 作為迴圈的調整,例如使迴圈變數增值,它是在執行完迴圈體後才進行的
//for語句的理解:
for (迴圈變數賦初值; 迴圈條件; 迴圈變數增值)
語句
for 語句的執行過程:
- 先求解表示式1
- 求解表示式2,若此條件表示式的值為真(非0)則執行 for 語句中迴圈體,然後執行第3步;若為假(0),則結束迴圈,轉到第5步
- 求解表示式3
- 轉回步驟2繼續執行
- 迴圈結束,執行 for 語句下面的一個語句
for 迴圈的過程:
//for 語句的一般形式:
for (表示式1; 表示式2; 表示式3)
語句
//改寫為 while 語句:
表示式1;
while (表示式2)
{
語句;
表示式3;
}
//二者無條件等價
“表示式1”可以忽略,即不設定初值,但是分號不能省略
“表示式2”可以忽略,即不用“表示式2”來作為迴圈條件表示式,不設定和檢查迴圈的條件
“表示式3”可以忽略
“表示式1”可以是設定迴圈變數初值的賦值表示式,也可以是與迴圈變數無關的其他表示式
“表示式3”也可以是與迴圈控制無關的任意表示式
“表示式1”和“表示式3”可以是一個簡單的表示式,也可以是逗號表示式,即包含一個以上的簡單表示式,中間用逗號間隔
在逗號表示式內按自左至右順序求解,整個逗號表示式的值為最右邊的表示式的值
“表示式2”一般是關係表示式或邏輯表示式,但也可以是數值表示式或字元表示式,只要其值為非零,就執行迴圈體
從終端鍵盤向計算機輸入時,是在按 Enter 鍵以後才將一批資料一起送到記憶體緩衝區中去的。
C語言的 for 語句比其他語言(如 FORTRAN,Pascal)中的 for 語句功能強得多。可以把迴圈體和一些與迴圈控制無關的操作也作為“表示式1”或“表示式3”出現,這樣程式可以短小簡潔。過分的利用這一特點會使 for 語句顯的雜亂,可讀性降低,最好不要把與迴圈控制無關的內容放到 for 語句中
迴圈的巢狀
一個迴圈體內又包含另一個完整的迴圈結構,稱為迴圈巢狀。內嵌的迴圈中還可以巢狀迴圈,這就是多層迴圈。各種語言中關於迴圈的巢狀的概念是一致的
3種迴圈( while 迴圈、do...while 迴圈和 for 迴圈)可以互相巢狀。
迴圈巢狀的例子:
幾種迴圈的比較
3種迴圈都可以用來處理同一問題,一般情況下它們可以互相代替
在 while 迴圈和 do...while 迴圈中,只在 while 後面的括號內執行迴圈條件,因此為了使迴圈能正常結束,應在迴圈體中包含使迴圈趨於結束的語句
for 迴圈可以在“表示式3”中包含使迴圈趨於結束的操作,甚至可以將迴圈體中的操作全部放到“表示式3”中。
for 語句的功能更強,凡是用 while 迴圈能完成的,用 for 迴圈都能實現
用 while 和 do...while 迴圈時,迴圈變數初始化的操作應在 while 和 do...while 語句之前完成,而 for 語句可以在“表示式1”中實現迴圈變數的初始化
while 迴圈、 do...while 迴圈和 for 迴圈,都可以用 break 語句跳出迴圈,用 continue 語句結束本次迴圈
改變迴圈執行的狀態
可以用 break 語句和 continue 語句來實現提前結束迴圈
用 break 語句提前終止迴圈
break 語句還可以用來寵迴圈體內跳出迴圈體,即提前結束迴圈,接著執行迴圈下面的語句
例:在全系1000學生中,徵集慈善募捐,當總數達到10萬元時就結束,統計此時捐款的人數,以及平均每人捐款的數目
//在全系1000學生中,徵集慈善募捐,當總數達到10萬元時就結束,統計此時捐款的人數,以及平均每人捐款的數目
#include <stdio.h>
int main(void)
{
int iTotle = 100000;
int iSum = 0;
int iCount = 0;
while (1)
{
int money;
printf("請輸入捐款數目\n");
scanf("%d", &money);
iSum += money;
iCount++;
if (iSum >= iTotle)
break;
}
printf("捐款人數%d,平均每人捐款的數目%lf", iCount, iSum / (double)iCount);
return 0;
}
執行結果:
break 語句的一般形式為:break;
其作用是使流程跳到迴圈體之外,接著執行迴圈體下面的語句
break 語句只能用於迴圈語句和 switch 語句之中,而不能單獨使用
用 continue 語句提前結束本次迴圈
例:要求輸出100~200之間的不能被3整除的數
//要求輸出100~200之間的不能被3整除的數
#include <stdio.h>
int main(void)
{
for (int i = 100; i < 201; i++)
{
if (0 == i % 3)
continue;
printf("%d\t", i);
}
return 0;
}
執行結果:
continue 語句的一般形式為:continue;
其作用為結束本次迴圈,即跳過迴圈體中下面尚未執行的語句,轉到迴圈體結束點之前,接著執行下一次迴圈
break 語句和 continue 語句的區別
continue 語句只結束本次迴圈,而不是終止整個迴圈的執行;而 break 語句則是結束整個迴圈過程,不再判斷執行迴圈的條件是否成立
如果是雙重迴圈,在內迴圈體內有一個 break 語句,是提前終止內迴圈,流程是跳轉到內迴圈體之外(執行內迴圈體下面的語句)
#include <stdio.h>
int main(void)
{
for (int i = 1; i < 5; i++)
{
for (int j = 1; j < 6; j++)
{
printf("%d\t", i * j);
if (5 != j)
continue;
printf("\n");
}
}
return 0;
}
執行結果:
迴圈程式舉例
#include <stdio.h>
#include <math.h>
int main(void)
{
double sun = 0;
for (int i = 1; ; i += 2)
{
if (0 == ((i / 2) % 2))
sun += 1.0 / i;
else
sun -= 1.0 / i;
if (fabs(1.0 / i) < 1E-6)
break;
}
printf("%lf", sun * 4);
return 0;
}
執行結果:
#include <stdio.h>
int main(void)
{
int f1 = 1, f2 = 1;
printf("%10d\t", f1);
printf("%10d\t", f2);
for (int i = 3; i < 41; i++)
{
int temp = f2;
f2 = f1 + f2;
f1 = temp;
printf("%10d\t", f2);
if (0 == (i % 5))
printf("\n");
}
return 0;
}
執行結果:
例:輸入一個大於 3 的整數 n,判定它是否為素數(prime,又稱質數)
//輸入一個大於 3 的整數 n,判定它是否為素數(prime,又稱質數)
#include <stdio.h>
int main(void)
{
int n;
while (1)
{
printf("請輸入一個大於3的整數\n");
scanf("%d", &n);
if (n > 3)
break;
}
for (int i = 2; i < n; i++)
{
if (0 == (n % i))
{
printf("不是素數\n");
return 0;
}
}
printf("是素數\n");
return 0;
}
執行結果:
例:求100~200間的全部素數
//求100~200間的全部素數
#include <stdio.h>
int main(void)
{
for (int i = 100; i < 201; i++)
{
char isPrime = 1;
for (int j = 2; j < i; j++)
{
if (0 == (i % j))
{
isPrime = 0;
break;
}
}
if (1 == isPrime)
printf("%d\t", i);
}
return 0;
}
執行結果:
#include <stdio.h>
int main(void)
{
char ch;
while ('\n' != (ch = getchar()))
{
if (((ch >= 'A') || (ch <= 'Z')) || ((ch >= 'a') || (ch <= 'z')))
{
ch = ch + 4;
switch (ch)
{
case 91:
ch = 'A';
break;
case 92:
ch = 'B';
break;
case 93:
ch = 'C';
break;
case 94:
ch = 'D';
break;
case 123:
ch = 'a';
break;
case 124:
ch = 'b';
break;
case 125:
ch = 'c';
break;
case 126:
ch = 'd';
break;
}
}
printf("%c", ch);
}
return 0;
}
執行結果: