C語言中文網 目錄

C語言循環結構(while循環,for循環,do…while循環)

使用循環可以多次重復地執行多條語句,這里的“多條語句”稱為循環體C語言中,可以使用三種循環,分別是:while、do...while和for。

在這些語句中,循環體被重復執行的次數由循環條件控制,稱為控制表達式(controlling expression)。這是一個標量類型的表達式,也就是說,它屬于一個算術表達式或指針表達式。如果控制表達式的值不等于 0,循環條件為 true,反之,循環條件為 false。

語句 break 和 continue 用于在一次循環還未執行完時,跳轉出循環或返回到循環頭部。

while 循環

只要控制表達式為 true,while 循環就會反復地執行語句:

while (表達式)語句


while 表達式是頂部驅動(top-driven)的循環:先計算循環條件(也就是控制表達式)。如果為 true,就執行循環體,然后再次計算控制表達式。如果控制表達式為 false,程序跳過循環體,而去執行循環體后面的語句。

從語法上講,循環體只有一條語句組成。如果需要執行多條語句時,可以使用語句塊把它們組合在一起。例 1 展示了一個簡單的 while 循環,從控制臺讀入多個浮點數,并把它們累加。

例 1 展示了一個簡單的 while 循環,從控制臺讀入多個浮點數,并把它們累加。

【例1】一個 while 循環
/* 從鍵盤輸入數字,然后輸出它們的平均值
* -------------------------------------- */
#include <stdio.h>
int main()
{
   double x = 0.0, sum = 0.0;
   int count = 0;
   printf( "\t--- Calculate Averages ---\n" );
   printf( "\nEnter some numbers:\n"
           "(Type a letter to end your input)\n" );
   while ( scanf( "%lf", &x ) == 1 )
   {
      sum += x;
      ++count;
   }
   if ( count == 0 )
     printf( "No input data!\n" );
   else
     printf( "The average of your numbers is %.2f\n", sum/count );
   return 0;
}

在例 1 中,只要用戶輸入一個小數,下面的控制表達式即為 true:
scanf( "%lf", &x ) == 1

然而,只要函數 scanf()無法將字符串輸入轉換成浮點數(例如,當用戶鍵入字母 q 時),則 scanf()返回值 0(如果是遇到輸入流的尾端或發生錯誤時,則返回值 -1,表示 EOF)。這時,循環條件為 false,程序將會跳出循環,繼續執行循環體后面的 if 語句。

for 循環

和 while 一樣,for 循環也是一個頂部驅動的循環,但是它包含了更多的循環邏輯,如下所示:

for ([表達式1];[表達式2];[表達式3])
    語句


在一個典型的 for 循環中,在循環體頂部,下述三個動作需要執行:

(1) 表達式 1:初始化
只計算一次。在計算控制表達式之前,先計算一次表達式 1,以進行必要的初始化,后面不再計算它。

(2) 表達式 2:控制表達式
每輪循環前都要計算控制表達式,以判斷是否需要繼續本輪循環。當控制表達式的結果為 false,結束循環。

(3) 表達式 3:調節器
調節器(例如計數器自增)在每輪循環結束后且表達式 2 計算前執行。即,在運行了調節器后,執行表達式 2,以進行判斷。

例 2 展示了使用一個 for 循環初始化數組內每個元素的過程。

【例2】用 for 循環初始化數組
#define ARR_LENGTH 1000
/* ... */
long arr[ARR_LENGTH];
int i;
for ( i = 0; i < ARR_LENGTH; ++i )
    arr[i] = 2*i;

for 循環頭部中的三個表達式可以省略一個或多個。這意味著 for 循環頭部最短的形式是:
for ( ; ; )

如果沒有控制表達式,則表示循環條件始終是 true,也就是說,這定義了一個死循環

下面所示的 for 循環,既沒有初始化表達式,也沒有調節器表達式,它與 while(表達式)語句含義是等效的:
for ( ;表達式; )

事實上,每個 for 循環都可以被改寫成 while 循環,反之亦然。例如,例 2 的 for 循環可完全等效為下面的 while 循環:
i = 0;                             // 初始化計數器
while ( i < ARR_LENGTH )     // 循環條件
{
    arr[i] = 2*i;
    ++i;                        // 遞增計數器
}

一般來說,當循環內有計數器或索引變量需要被初始化,并且在每次循環時需要調整它們的值時,最好使用 for 循環,而不是 while 循環。

在ANSI C99中,也可以使用聲明來替代表達式1。在這種情況下,被聲明變量的作用域被限制在 for 循環范圍內。例如:
for ( int i = 0; i < ARR_LENGTH; ++i )
    arr[i] = 2*i;

變量 i 被聲明在該 for 循環中(與例 2 不同)for 循環結束之后,變量 i 將不會再存在。

逗號運算符常常被用在 for 循環頭部,以在表達式 1 中實現多個初始化操作,或者在表達式 3 對每個變量做調整操作。例如,函數 strReverse()使用兩個索引變量以保存字符串中字符的次序:
void strReverse( char* str)
{
  char ch;
  for ( size_t i = 0, j = strlen(str)-1; i < j; ++i, --j )
    ch = str[i], str[i] = str[j], str[j] = ch;
}

借助于逗號運算符,可以在只允許出現一個表達式的地方,計算多個表達式。

do...while 循環

do...while 循環是一種底部驅動的循環

do 語句 while (表達式);


在控制表達式被第一次計算之前,循環體語句會首先被執行一次。與 while 和 for 循環不同,do...while 循環會確保循環體語句至少執行一次。如果控制表達式的值為 true,那么另一次循環就會繼續;如果是 false,則循環結束。

在例 3 中,讀入與執行命令的函數至少會被調用一次。當使用者離開菜單系統,函數 getCommand()將返回常量 END 的值。

【例3】do···while
// 讀入和執行所選的菜單命令
// --------------------------------------------
int getCommand( void );
void performCommand( int cmd );
#define END 0
/* ... */
do
{
  int command = getCommand();   // 詢問菜單系統
  performCommand( command );    // 執行所選的菜單命令
} while ( command != END );

例 4 展示了標準庫函數 strcpy()的一個版本,循環體僅為一條簡單的語句,而不是一個語句塊。因為在循環體執行之后才計算循環條件,所以字符串終止符'\0'也會被復制。

【例4】函數 strcpy()使用 do...while
// 將字符串2復制到字符串1
// ----------------------------
char *strcpy( char* restrict s1, const char* restrict s2 )
{
  int i = 0;
  do
     s1[i] = s2[i];               // 循環體:復制每一個字符
  while ( s2[i++] != '\0' );      // 如果剛剛復制的是'\0',則結束循環
  return s1;
}

精美而實用的網站,提供C語言C++STLLinuxShellJavaGo語言等教程,以及socketGCCviSwing設計模式JSP等專題。

Copyright ?2011-2018 biancheng.net, 陜ICP備15000209號

底部Logo