詳細介紹了C語言while循環結構、do-while循環結構、for循環結構、循環退出語句的語法和使用方法。
1、while循環結構
while循環循環結構的必要性
前面討論了編程中進行判斷的各種方法,然而有些問題僅僅通過判斷還不能解決。某些情況中,為解決一個問題常常需要重復執行一個或多個操作。例如,要求輸出從1—5分別乘以10所得的乘法表。
例: 輸出從1—5分別乘以10所得的乘法表
程序清單 sample.c
#include
int main()
{
int result1,result2,result3,result4,result5;
result1 = 1 * 10;
printf("1 * 10 = %dn",result1);
result2 = 2 * 10;
printf("2 * 10 = %dn",result2);
result3 = 3 * 10;
printf("3 * 10 = %dn",result3);
result4 = 4 * 10;
printf("4 * 10 = %dn",result4);
result5 = 5 * 10;
printf("5 * 10 = %dn",result5);
}
程序編寫5條語句計算乘積,再編寫另外5條語句顯示這些乘積。如果要求輸出1—100的數與10相乘的乘法表呢?就需要重復編寫100次這樣的語句。這樣既費時又費力。我們需要一種方法可以快速有效地執行重復性操作。在C語言中,可以通過循環結構來解決這類問題。
循環結構是程序中一種很重要的結構。其特點是,在給定條件成立時,重復執行某程序段,直到條件不成立為止。給定的條件為循環條件,反復執行的程序段稱為循環體。C語言提供了三種不同形式的循環結構。
(1) while循環結構
用于在特定條件為真的情況下重復執行某些操作,在執行循環體之前先檢查條件,一旦條件為假,循環就停止。
(2) do—while循環結構
同樣用于在特定條件為真的情況下重復執行某些任務。但是在do—while循環中,是在執行循環語句之后再檢查條件。因此,在循環結束前,循環體內的語句至少會被執行一次。
(3)for循環結構
fou循環與while循環在功能上類似,只要條件為真,就會執行循環體中的語句。同樣,也是在執行循環語句之前先檢查條件,但是,其語法規則與while循環有所不同。
while循環
while循環的一般語法是:
while( 表達式 )
語句;
其中,表達式是循環條件,語句為循環體。while語句的語義是:計算表達式的值,當值為真(非0)時,執行循環體語句,一旦條件為假,就停止執行循環體。如果條件在開始時就為假,則不執行循環體語句直接退出循環。
循環體語句可以是空語句、單條語句或語句集。如果是語句集,則要用“{”和“}”把它們括起來,用于循環條件的表達式必須返回真或假。
例:輸出從1—10分別乘以10所得的乘法表
程序清單 sample.c
#include
int main()
{
//聲明變量num,初值為1
int num=1;
// 聲明變量result,存儲計算結果
int result;
while( num <=10 )
{
result = num * 10;
printf(" %d * 10 = %d n",num,result);
//使用自增運算符,修改循環變量
num++;
}
}
程序聲明了兩個int類型的變量num和result,分別用來存儲數字和乘積。然后,將num初始化為1,因為打算在while循環中從1開始執行乘法運算,求出1—10的數字與10的乘積,因此將while循環的條件編寫為num<=10。這樣確保了只要num小于等于10,就執行while循環;而當此條件變為假時,即num的值達到11時,就結束此循環。循環體中的第一個語句用num乘以10,將計算結果保存在變量result中。第二個語句輸出乘法表,循環體中的最后一個語句將num的值遞增1,來修改num的值。此處使用了單目自增運算符++,也可以編寫為num=num+1,來替代num++。
程序中的num++非常重要,這條語句通過修改num的值來修改循環條件,直到num的值等于11,循環條件為假時退出循環。也就是說,循環條件中的變量,需要在循環中重新賦值,以逐漸改變循環條件的值,直到循環條件為假;否則循環將永遠不會停止,這種循環稱為“死循環”或者“無限循環”。
例:無限循環
程序清單 sample.c
#include
int main()
{
int count=0;
while( count < 100 )
{
printf("這將沒完沒了,幫幫我吧?。。?);
printf("試試Ctrl+C吧");
}
}
程序功能主要是演示在while循環語句中,由于缺乏改變條件的語句而導致出現無限循環的問題。
程序中while循環體內沒有修改循環變量count的值,導致循環條件一直為真,造成了無限循環。
2、do-while循環
do-while循環與while循環的不同在于:它先執行循環體中的語句,然后再判斷條件是否為真。如果為真則繼續循環,如果為假,則終止循環。因此,do-while循環至少要執行一次循環語句。同樣當有許多語句參加循環時,要用“{”和“}”把它們括起來。
do-while循環的一般語法是:
do{
語句;
}while(條件)
注意:在do-while語句的表達式后面必須加分號。
例:do-while循環練習
編程要求:編寫一個猜數游戲,要求猜一個介于1—10之間的數字,根據用戶猜測的數與標準值進行對比,并給出提示,以便下次猜測能接近標準值,直到猜中為止。
程序清單 sample.c
int main()
{
//初始化猜數的標準數值
int number = 5;
int guess = 0;
printf("猜一個介于 1 與 10 之間的數n");
do
{
printf("請輸入您猜測的數:");
scanf("%d",&guess);
if( guess > number )
printf("太大n");
else if( guess < number )
printf("太小n");
}while( guess != number );
printf("您猜中了:答案為 %dn",number);
}
程序內部設置一個標準值(答案)存儲到變量number中,并聲明一個guess變量接收用戶猜測的數值。采用do-while結構可以確保用戶至少能進行一次猜數操作,在循環體內,提示用戶輸入要猜的數,用戶輸入猜測的數值后,利用if-else語句和正確答案進行判斷,如果用戶猜測的數值大于答案,提示用戶數太大;如果用戶猜測的數值小于答案,提示用戶數太小。while語句后面的表達式( guess != number )用于判斷循環條件是否滿足,如果用戶輸入的數值和答案不相等,該表達式返回的結果為真,繼續執行循環體,要求用戶根據提示繼續猜數,否則,表達式返回的結果為假,循環條件不滿足,程序不再執行循環體,直接執行循環體后面的語句。
do-while語句是一種先執行循環體,然后判斷條件的結構,即只有在循環體中的代碼執行之后,才會判斷循環條件。總的來說,循環結構在開始執行的時候,先執行循環體內的代碼,然后通過while里面的條件進行判斷,條件成立就繼續執行循環,不成立就跳出循環,循環體內代碼至少被執行一次。
3、嵌套循環
就像if語句可以嵌套一樣,一個循環也可以嵌套在另一個循環中,一個循環中含有另一個循環就稱為嵌套循環。
嵌套循環的工作原理如下:首先外循環的第一輪觸發內循環,然后內循環將一直執行到完成為止,然后,外循環的第二輪再次觸發內循環,此過程不斷重復直到外循環結束,使用嵌套循環時,只有在內循環完全結束后,外循環才會執行下一趟循環,
一個while循環可以嵌套在另一個while循環中,示例1演示了嵌套while循環的用法。
例:while嵌套循環練習1
編程要求:用*輸出一個直角三角形圖案。
程序清單 sample.c
#include
void main()
{
int nstars=1,stars;
//外層循環控制輸出*的行數
while( nstars <= 10 )
{
stars = 1;
//內層循環控制打印星號的數量
while( stars <= nstars )
{
printf("*");
stars++;
}
printf("n");
nstars++;
}
}
程序用外層循環控制輸出 的行數,循環條件為nstars <= 10,nstars初始化為1,該條件允許輸出10行 ;內層循環控制*輸出的數量,循環條件為stars <= nstars,內層循環開始前,stars都被賦值為1,然后在內層循環體內做自增操作。
例:while嵌套循環練習2
編程要求:輸入字符序列,統計輸入的字符數。
程序清單 sample.c
#include
void main()
{
int x;
char ans;
ans = 'y';
do {
x = 0;
printf("請輸入字符序列:n");
do {
scanf("%c",&ans);
x++;
}while( ans != 'q');
printf("n輸入的字符數為:%d",--x);
printf("n是否需要輸入更多字符序列(Y/N)?");
scanf("%c",&ans);
}while( ans!='N' );
}
程序首先提示用戶輸入字符序列,進入內層do-while循環,接收用戶輸入的字符序列,直到用戶按下回車鍵并輸入字符q,程序將退出內層的do-while循環。程序接著詢問用戶是否要輸入更多的字符序列,如果用戶輸入y或Y,do-while外循環的條件為真,則程序將提示用戶輸入另一序列字符。直到用戶按下除y或Y以外的任何鍵時,外循環才結束。
while循環和do-while循環也可以互相嵌套。例如,可以將示例1的內層while循環修改為do-while循環,或者將外層循環修改為do-while循環。
4、for循環
for循環語句是C語言提供的功能更強,使用更廣泛的一種循環語句。C語言的for循環語句使用最為靈活,不僅可以用于循環次數已經確定的情況,而且可以用于循環次數不確定而只給出循環條件的情況,它完全可以代替while循環。
for循環的一般語法為:
for(表達式1; 表達式2; 表達式3;)
{
語句;
}
語法說明如下:
■ 表達式1:通常用來給循環變量賦初值,一般是賦值表達式,也允許在for語句外給循環變量賦初值,此時可以省略該表達式;
■ 表達式2:通常是循環條件,一般為關系表達式或邏輯表達式;
■ 表達式3:通??捎脕硇薷难h變量的值,一般是賦值語句。
for循環中的這三部分必須用分號隔開,組成循環體的語句可以是單條語句或一個語句集(多條語句)。
一般語法中的“語句”即為循環體語句。for語句的語義是:
- 首先計算表達式1的值,通常為循環變量賦初值;
- 再計算表達式2的值,即判斷循環條件是否為真,若值為真則執行循環體一次,否則跳出循環;
- 然后再計算表達式3的值,這里通常寫更新循環變量的賦值表達式,然后轉回第二步重復執行。
在整個for循環過程中,表達式1只計算一次,表達式2和表達式3則可能計算多次。循環體可能執行多次,也可能一次都不執行。
例:for循環練習1
編程要求:使用for循環求數的階乘。
程序清單 sample.c
#include
void main()
{
int number,count;
int factorial = 1;
printf("請輸入任意一個正整數:");
scanf("%d",&number);
for( count=1;count<=number;count++ )
{
factorial = factorial * count;
}
printf("%d的階乘 = %d",number,factorial);
}
程序聲明了3個int類型的變量,number、count、factorial。分別用于存儲輸入的整數、循環變量的值、階乘值。For循環中表達式count=1為變量賦初值,表達式count<=number作為循環條件用來測試是否繼續執行循環,表達式count++用來修改循環變量的值。
for語句中的三個表達式都可以是逗號表達式,逗號表達式就是通過“逗號”隔開的多個表達式組成的表達式,逗號表達式從左往右計算。
例:for循環練習2
編程要求:使用for循環輸出加法表。
程序清單 sample.c
#include
void main()
{
int i,j,max;
printf("請輸入任意一個數值:");
printf("根據這個值可以輸出以下加法表n");
scanf("%d",&max);
for( i=0,j=max;i<=max;i++,j-- )
{
printf("n %d + %d = %d",i,j,i+j);
}
}
程序在for循環中,表達式1為逗號表達式,該表達式為循環變量i和j賦初值,執行此表達式后,i被賦值為0,j被賦予max中的當前值;表達式3也是一個逗號表達式,每次循環后,i自加1,j自減1。
前面已討論,for循環中有三個表達式,for循環中的這三個表達式都可以省略,但要注意分號分割符合不能省略,下面分別討論for循環中省略部分或者全部表達式的情況。
(1)省略表達式1
for循環語句中表達式1可以省略不寫,此時,循環變量應在循環語句之外賦值,例如如下語句:
int i = 0;
for( ; i < 10; i++ )
{
printf("n %d=", i*2)
}
程序輸出20以內的偶數,int i = 0對循環變量進行賦值,因為循環變量i已經被賦值,此時循環語句可以省略表達式1。
(2)省略表達式2
for循環語句中的表達式2,在一定條件下也可以省略, 表達式2主要用于循環條件的判斷。如果省略表達式2,就必須要在循環體中增加循環條件判斷語句,如果不滿足循環條件,則跳出循環。跳出循環可以用break語句,break語句將在后面介紹。省略表達式2的示例語句如下:
int i;
for( i=0;; i++ )
{
if( i >=10 )
break;
printf("n %d=", i*2)
}
程序在循環體內增加了if( i >= 10 )條件判斷語句,如果i>=10為真,則通過break語句跳出循環,如果循環體內沒有跳出循環的條件判斷語句,程序將進入無限循環。
(3)省略表達式3
for循環語句中的表達式3一般是用來修改循環變量的值,如果在循環體內有修改循環變量的語句,此時表達式3可以省略。例如如下語句:
int i;
for( i=0; i< 10; )
{
i = i+1;
printf("n %d=", i*2)
}
循環體內的i = i+1等同于for( ; i < 10; i++ )語句中的i++,每循環一次,i就進行加1操作,當i自增到10時,循環終止。
三個表達式都省略
三個表達式都省略的情況比較少見,此時,循環體為有循環變量的賦值語句,循環體內應有修改循環變量和循環條件判斷的語句,否則很容易形成無限循環。例如如下語句:
int i=0;
for( ;; ; )
{
i = i+1;
if( i >=10 )
break;
printf("n %d=", i*2)
}
程序中int i=0為循環變量i賦初值,循環體內i = i+1修改循環變量i的值,if( i >= 10 )判斷循環變量i的值是否大于等于10,如果條件為真,則跳出循環。
for循環在C編程中應用非常廣泛,它不僅可以用于循環次數已經確定的情況,而且可以用于循環次數不確定而只給出循環條件的情況,它完全可以代替while循環。只要弄明白了for循環的三個表達式,就可以掌握for循環的用法,表達式1是進入第一次for循環之前運行,并且只會執行一次;表示式2是for循環的執行條件,滿足這個條件后才能進入循環里面的語句;表達式3是在執行一次循環后執行的語句。
5、循環跳出
有時可能不知道循環將要執行的次數,終止循環的條件可在以后確定,所以需要提供一種機制在條件滿足的時候跳出循環。有時候,我們需要根據條件跳過循環中的一些語句。Java語言提供了break和continue兩個關鍵字,用于改變程序的控制流。
break語句
break語句通常用在前面介紹過的switch語句及循環語句中。當break語句用于switch語句時,可使程序跳出switch語句而執行switch語句之后的語句;當break語句用于while、do-while、for循環語句時,可使程序終止循環而執行循環后面的語句。
break語句實際上就是為了使人能方便地描述從循環執行中退出的動作。通常應把break語句放在條件語句控制之下,以便在某些條件成立時立即結束循環。
例:break語句練習
編程要求:使用break語句退出循環。
程序清單 sample.c
#include
void main()
{
int i= 0;
while(i< 7)
{
i++;
printf("n 第%d次循環",i);
if(i==5)
{
printf("n i==5 跳出循環,程序結束", i);
break;
}
}
}
該循環在變量i的值等于5時,滿足條件,然后執行break語句,結束整個循環,循環語句后面沒有其它語句可執行,程序退出。
continue語句
continue語句只能用在循環里。continue語句的作用是跳過循環體中剩余的語句而準備執行下一次循環。對于while和do-while循環,continue執行之后的動作是條件判斷;對于for循環,隨后的動作是變量更新。
注意break語句和continue語句的差別。break語句導致循環終止,使程序控制流轉向這個循環語句之后;而continue引起的則是循環內部的一次控制轉移,使執行控制跳到循環體的最后,相當于跳過循環體里這個語句后面的那些語句,繼續下一次循環,下圖說明了break語句和continue語句引起的控制轉移的情況。
例:continue語句練習
編程要求:求整數1—100的累加值,但要求跳過所有個位為3的數。
提示:在循環中加一個判斷,如果該數個位是3,就跳過該數不加。如何判斷1到100中的那些整數的個位是3呢,還是使用取余運算符“%”,將一個正整數,除以10以后余數是3,就說明這個數的個位為3。
程序清單 sample.c
#include
void main()
{
int i;
int sum = 0;
for( i =1; i<=100; i++ )
{
if( i % 10 == 3 )
{
continue;
}
sum += i;
}
printf("sum = %d",sum);
}
程序檢查i除以10的余數是否等于3,如果是,則意味該數的個位數是3,這種情況下,將使用continue語句跳過后續語句,然后轉向for循環的表達式3更新循環變量,繼續下一次循環。
和break語句一樣,continue語句通常在循環中與條件語句一起使用,用來控制循環。在循環中遇到continue語句后,就不會執行該循環中位于continue后的任何語句。continue語句用于結束當次循環,繼續下一次循環。
6、for嵌套循環
for循環也可以嵌套,它可以和for循環結構,也可以和while循環結構混合嵌套。
嵌套循環時,必須將被嵌套的循環語句完整地包含在外層循環的循環體內,下面給出嵌套循環的示例。
例:for循環嵌套練習
編程要求:用“*”輸出一個菱形圖案,圖案如下:
程序清單 sample.c
#include
void main()
{
int i, j, k;
// 先打印上邊的四行
for (i = 1; i <= 4; i++) {
// 控制要打印的空格數
for (j = 1; j <= 4 - i; j++)
printf(" ");
// 控制要打印的星號數
for (k = 1; k <= 2 * i - 1; k++)
printf("*");
printf("n");
}
// 打印下邊的三行
for (i = 1; i <= 3; i++) {
// 控制要打印的空格數
for (j = 1; j <= i; j++)
printf(" ");
// 控制要打印的星號數
for (k = 1; k <= 7 - 2 * i; k++)
printf("*");
printf("n");
}
}
程序分為兩部分循環,第一部分循環輸出菱形圖案的上邊四行,最外層循環控制輸出的行數,內層嵌套了兩個for循環,第一個嵌套循環輸出打印的空格數,第二個嵌套循環輸出打印的星號數;第二部分循環輸出菱形圖案的下邊三行,原理和第一部分循環相同。
例:for循環嵌套練習
編程要求:打印輸出100至200之間的全部素數。
提示:素數是指能被1和它本身整除的數。算法比較簡單,先將這個數被2除,如果能整除,且該數又不等于2,則該數不是素數。如果該數不能被2整除,再看是否能被3整除,并且該數不等于3,則該數不是素數,否則再判斷是否能被4整除,依次類推,該數只要是能被小于其本身的某個數整除時,就不是素數。
程序清單 sample.c
#include
void main()
{
int i, j, n;
n = 0;
for (i = 100; i <= 200; i++) {
j = 2;
// 從2到i之間尋找第一個能被整除的數
while (i % j != 0)
j++;
// 如果第一個能被整除的數等于該數本身,則說明該數為素數
if (i == j) {
printf("%4d", i);
n++;
// 控制每行輸出8個素數
if (n % 8 == 0)
printf("n");
}
}
printf("n");
}
程序外層循環控制輸出100至200之間的數,內層的while循環用于找尋從2到該數之間第一個能被整除的數,內層循環判斷條件為i%j != 0,其中i為當前要判斷是否是素數的數,j為從2開始循環遞增的數,如果i%j != 0,則說明i不能被j整除,j自增后程序繼續執行while循環,如果i%j == 0,則說明i能被j整除,程序跳出while循環,循環后面的if語句判斷i與j是否相等,如果相等,則說明i為素數,程序輸出i。
評論