上一節講了while循環結構的格式及編程方法,while循環結構是先判斷條件表達式,條件為真則執行循環體,條件為假則退出循環。如果第一次判斷條件不成立,循環體一次也不會被執行,所以又稱為“當型循環”。本節主要講另一種循環——do_while循環,又稱為“直到型”循環,這種循環會先執行一次循環體,再進行條件判斷,當條件為假時結束循環。
do_while循環結構的一般形式為:
do
S
while(表達式);
S稱為循環體,可以是空語句、簡單語句或複合語句,最後一個分号“;”是語句的結束符号,不能省略。do_while是先執行一次循環體S,再進行表達式計算并判斷,如果結果為真,繼續重複執行循環體S。執行過程如流程圖:
do_while循環流程圖
以下形式是合法的do_while形式。
(1)
i=10;
do ; while(--i);
(2)
i=10;
do printf("*"); while(--i);
(3)
i=10;
do{
printf("*");
--i;
}while(i>=0);
(1)的循環體是一條空語句(;),且被執行了10次,但什麼也沒幹,循環結束後i變成了0;(2)和(3)功能是一樣的,都是在屏幕上顯示10個*号,(3)用複合語句作循環體,(2)用單條語句作循環體,計算--i表達式後再判斷結果是否為真,顯得要緊湊一些。
與while循環不同,do_while是先執行一次循環體,再進行條件判斷,因此這種循環至少會被執行一次。我們可以把前面一些用while實現的程序改寫成用do_while實現,如求100的累加和,用while實現時是這樣的:
sum=0;i=1;
while(i<=100){
sum=sum i;i ;
}
而改成用do_while實現變成:
sum=0;i=1;
do{
sum=sum i;i ;
}while(i<=100);
兩段代碼在求100的累加和時寫法雖不同,但結果都是一樣的,都是在i為101時退出循環。但是在求前n項的累加和時卻未必等價,設n由鍵盤輸入,前面兩段程序可以寫為:
(1)用while實現
sum=0;i=1;
scanf("%d",&n);
while(i<=n){
sum=sum i;i ;
}
(2)用do_while實現
sum=0;i=1;
scanf("%d",&n);
do{
sum=sum i;i ;
}while(i<=n);
兩個程序分别執行後,當輸入大于0的數時,兩個程序的運算結果一樣。但是當輸入0時,結果還一樣嗎?代碼(1)的sum為0,因為循環體一次也沒執行;而代碼(2)的結果為1,因為循環體執行了一次,1被加進了sum中。可見前n項累加和的程序,用while和do_while實現存在細微差别,用do_while并不完全正确。
例1:從鍵盤讀入一個整數,統計該數的位數并輸出。
如輸入495,輸出結果為3。如果輸入0至9的一個數,則輸出結果為1。
我們知道任何一個整數,其絕對值總是可以寫為:
n=m*10 r;
其中,r稱為n的個位,m是n整除以10後(丢掉個位)的結果。因此一個整數,可以可以拆分為m和r兩個部分,m的位數剛好是n丢掉個位的數,r隻有一位。如:
495 可拆分為m=49,r=5;
49又可拆分為m=4,r=9;
4又可拆分為 m=0,r=4;
當拆分到m為零時,拆分結束。從上述的分析可知一個具有k位的整數可以被拆分k次,每次從右到左依次把相應位丢掉,至到所有位全部拆分出為止(此時m==0)。由于我們不關心拆出來的位用來幹什麼,我們直接把整數的後一位丢掉就行,因此,丢掉n的個位的代碼為:
m=n/10;
m就是n丢掉了個位後乘餘的數,設一個計數變量cnt統計丢掉的位的數,因為每做一次m=n/10就丢掉一個位,因此接着要讓cnt加1。循環體變為:
m=n/10;
cnt=cnt 1;
因為還要繼續對m進行拆分,所以下一次執行循環時變量n要變為m的值,也就是要把m賦給n,循環體變為:
m=n/10;
cnt=cnt 1;
n=m;
考慮循環體第1行和第3行之間,m沒有發生變化,所以兩句可以合并為一句,即n=n/10,循環體變為:
n=n/10;
cnt=cnt 1;
由于循環執行的條件是n>0,因此可以用while語句構造循環如下:
while(n>0){
n=n/10;
cnt=cnt 1;
}
當n為大于0的整數時,while循環總能得到正确結果。但是當n=0時,循環體一次也不執行,cnt為0,而正确結果應為1。因此可以用do_while循環解決n為0的問題。用do_while寫的代碼如下:
do{
n=n/10;
cnt=cnt 1;
}while(n>0);
這樣程序就更加完整了,輸入任何合法的整數總能得到正确的結果。完整的程序如下:
#include <stdio.h>
int main(void)
{
int cnt=0;
int n;
printf("Enter a integer:");
scanf("%d",&n);
if(n<0) n=-n;
do{
n=n/10;
cnt=cnt 1;
}while(n>0);
printf("it contains %d digits!\n",cnt);
return 0;
}
程序中考慮了n為負整數的情況,當n為負整數時先要變成其相反數。思考一下,如果要用while循環,如何修正剛才的n為0時的錯誤!
例2:用do_while語句根據格雷戈裡公式計算π值,要求最後一項精度小于10^-4。
由于結束循環使用item的絕對值小于10^-4,因此程序與while版本的功能一樣,隻是循環構造略有不同。
#include<stdio.h>
#include<math.h>
int main( )
{
int flag,d;
double item,sum,pi;
item=1;
d=1;
flag=1;
do{
sum=sum item;
d=d 2;
flag=-flag;
item=flag*1.0/d;
}while(fabs(item)>=1e-4);
pi=4*sum;
printf("pi=%f\n",pi);
}
大部分情況下,用do_while可以完成的循環,稍作補充和修改也可以用while完成,針對do_while至少執行一次循環體的特例在while中要作特殊處理。如在例1中,如果要想用while代替do_while,要對n=0的情況進行特殊處理。
本節主要介紹了do_while循環的格式和執行過程,比較了while與do_while語句構造循環異同,介紹了兩種循環結構的相互替代方法。本節就講到這裡,下節再見。
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!