循環結構程序設計


前言

 循環結構是C語言三大基本結構之一,是結構化程序設計中最重要的結構。循環結構程序主要使用循環語句實現(循環語句是專門用於循環程序執行流程的語句)。在C語言中,主要有for循環語句,while語句,do-while語句,和goto語句(由於過多的goto語句會破壞程序完整的邏輯性,這里我們不做重點介紹)。


 循環結構即在給定條件成立的條件下,反復執行某語句段,直到條件不成立為止,我們將給定的條件成為循環條件,反復執行的語句稱為循環體。
 根據循環條件和循環體執行次序,可以分為當型循環、直到型循環。在WHILE(當型)語句中,是當條件滿足時執行循環體;而在UNTIL(直到型)語句中,是當條件不滿足時執行循環體。

  • 當型循環
    圖1
    圖2

 當計算機遇到WHILE語句時,先判斷條件的真假,如果條件符合,就執行WHILE與WEND之間的循環體;然后再檢查上述條件,如果條件仍符合,再次執行循環體,這個過程反復進行,直到某一次條件不符合為止。
 這時,計算機將不執行循環體,直接跳到WEND語句后,接着執行WEND之后的語句。因此,當型循環有時也稱為“前測試型”循環。

  • 直到型循環
    圖3

 直到型循環又稱為“后測試型”循環,從UNTIL型循環結構分析,計算機執行該語句時,先執行一次循環體,然后進行條件的判斷,如果條件不滿足,繼續返回執行循環體,然后再進行條件的判斷。
 這個過程反復進行,直到某一次條件滿足時,不再執行循環體,跳到LOOP UNTIL語句后執行其他語句,是先執行循環體后進行條件判斷的循環語句。

For循環語句

 for語句屬於直到型循環,使用非常廣泛。

For語句定義

 for語句由初始表達式,循環控制表達式,循環置位表達式和循環體構成。其一般形式為:

for(表達式1;表達式2;表達式3)
{
  語句段
}

//注釋
 表達式1稱為初始表達式,作為for語句初始條件,常常用來給循環變量賦初值,一般為賦值表達式
 表達式2稱為循環控制表達式,通常作為循環條件,一般為邏輯表達式
 表達式3稱為循環置位表達式,即迭代表達式,用來修改循環變量的值
 上述表達式既可以是單個語句,也可以是由多個表達式構成的逗號表達式

為了更好地理解定義,我們給出一個具有趣味性的例子:

for(time=now;time<=forever;time++)
{
  love++;
  happiness++;
}
//注釋
 結合程序猿的三行情詩,我們可以更好地理解for語句。
 time=now即為表達式1,為初始表達式,意思是從現在開始
 time<=forever即為表達式2,為循環控制表達式,意思是直到永遠
 time++即為表達式3,為循環置位表達式,意思是隨着時間流逝
 love++;happiness++;為語句段,意思是每天多愛你一點點,每天幸福一點點
所有結合起來的意思,不用我多說了吧。

 需要注意的有,三個表達式僅僅作為執行某項功能存在,如果存在其他語句代替某一個表達式的功能,則在括號中該語句可以省略。(也就意味着不是每一個循環語句都具有完整的三個表達式),但分號不能省略。

 關鍵字for與括號之間沒有空格,也可以加上一個空格來使代碼美觀整齊。

for語句的執行過程

 for語句按照從左到右,從上到下,自兩邊到中間的執行順序執行,具體執行步驟為:

  1. 先執行“表達式1”。

  2. 再執行“表達式2”,如果它的值為真(非0),則執行循環體,否則結束循環。

  3. 執行完循環體后再執行“表達式3”。

  4. 重復執行步驟 2) 和 3),直到“表達式2”的值為假,就結束循環。

上面的步驟中,2) 和 3) 是一次循環,會重復執行,for 語句的主要作用就是不斷執行步驟 2) 和 3)。

在整個for循環執行過程中,表達式2是for循環的控制表達式,對循環語句執行起主要的控制作用。

 畫出執行流程圖,如下所示:

 在源代碼中執行順序為:

for語句應用實例

//從1一直加到100

#include <stdio.h>
int main(){
    int i, sum=0;
    for(i=1; i<=100; i++){
        sum+=i;
    }
    printf("%d\n",sum);
    return 0;
}

運行結果:
5050

執行流程為:

  1. 執行到 for 語句時,先給 i 賦初值1,判斷 i<=100 是否成立;因為此時 i=1,i<=100 成立,所以執行循環體。循環體執行結束后(sum的值為1),再計算 i++。

  2. 第二次循環時,i 的值為2,i<=100 成立,繼續執行循環體。循環體執行結束后(sum的值為3),再計算 i++。

  3. 重復執行步驟 2),直到第101次循環,此時 i 的值為101,i<=100 不成立,所以結束循環。

for語句的三個表達式具體分析

for循環中的“表達式1(初始化條件)”、“表達式2(循環條件)”和“表達式3(自增或自減)”都是可選項,都可以省略(但分號;必須保留)

我們以上面的程序為例,進行分析:

  • 省略表達式1(初始化條件)
int i = 1;
for( ; i<=100; i++)
{
    sum+=i;
}
  • 省略表達式2(循環控制表達式)
for(i=1; ; i++) 
  sum=sum+i;

如果不做其它處理就會成為死循環(循環條件永遠成立,循環會一直進行下去,永不結束)

  • 省略表達式3(循環置位表達式)
for( i=1; i<=100; )
{
    sum=sum+i;
    i++;
} 

省略了“表達式3(自增或自減)”,就不會修改“表達式2(循環條件)”中的變量,這時可在循環體中加入修改變量的語句

  • 補充兩個經常使用的特殊for語句

無限循環語句

for( ; ; )
{
  語句段;
}

重復讀取語句

for( ; (c=getchar())!='\n' ; )
    printf("%c",c);

for語句的嵌套使用

 嵌套規則很簡單,我們給出一般形式,然后用實例進行學習

  • for語句嵌套定義

一般形式為:

for(表達式01;表達式02;表達式03)
  for(表達式11,;表達式12,;表達式13)
    …………
      for(表達式n1;表達式n2;表達式n3)
      {
        語句段;
      }
//一般情況下n<=3;
  • 實例分析:打印九九乘法表

 這里我們需要用雙重循環完成打印九九乘法表的任務,這里我們給出代碼和分析:

#include<stdio.h>

int main()
{
  int i=0,j=0;
  int mult=0;
  for(i=1;i<=9;i++)//打印控制行
  {
    for(j=1;j<=i;j++)
    {
      printf("%d*%d=%-3d",j,i,i*j);
    }
    printf("\n");
  }
  return 0;
}

執行結果:

1*1=1  
1*2=2  2*2=4  
1*3=3  2*3=6  3*3=9  
1*4=4  2*4=8  3*4=12 4*4=16 
1*5=5  2*5=10 3*5=15 4*5=20 5*5=25 
1*6=6  2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 
1*7=7  2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 
1*8=8  2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 
1*9=9  2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81 

分析:

 程序將i作為內層循環的控制變量,控制列輸出總是小於等於行輸出數,程序輸出結果為i*j=k格式的等式,實現了九九乘法表的效果,使用%3d格式輸出乘積,實現對齊效果。

While語句與do-while語句

while語句和for語句一樣屬於直到型語句,do-while語句屬於當型語句。

while語句定義及應用

while循環的一般形式為:

while(表達式){
    語句塊
}

 即先計算“表達式”的值,當值為真(非0)時, 執行“語句塊”;執行完“語句塊”,再次計算表達式的值,如果為真,繼續執行“語句塊”……這個過程會一直重復,直到表達式的值為假(0),就退出循環,執行 while 后面的代碼。

 通常將“表達式”稱為循環條件,把“語句塊”稱為循環體,整個循環的過程就是不停判斷循環條件、並執行循環體代碼的過程。

實例:

//計算1加到100的值

#include <stdio.h>
int main(){
    int i=1, sum=0;
    while(i<=100)
    {
        sum+=i;
        i++;
    }
    printf("%d\n",sum);
    return 0;
}

運行結果:
5050

執行過程:

  1. 程序運行到 while 時,因為 i=1,i<=100 成立,所以會執行循環體;執行結束后 i 的值變為 2,sum 的值變為 1。

  2. 接下來會繼續判斷 i<=100是否成立,因為此時 i=2,i<=100 成立,所以繼續執行循環體;執行結束后 i 的值變為 3,sum 的值變為3。

  3. 重復執行步驟 2)。

  4. 當循環進行到第100次,i 的值變為 101,sum 的值變為5050;因為此時 i<=100 不再成立,所以就退出循環,不再執行循環體,轉而執行while循環后面的代碼。

由此,我們可以得到while 循環的思路:

  • 設置一個帶有變量的循環條件,也即一個帶有變量的表達式;
  • 在循環體中額外添加一條語句,讓它能夠改變循環條件中變量的值。
  • 隨着循環的不斷執行,循環條件中變量的值也會不斷變化,當循環條件不再成立,循環結束

當循環條件中沒有變量時,可以分為兩種情況:

  • while(1)
#include <stdio.h>
int main()
{
    while(1)
    {
        printf("666");
    }
    return 0;
}

運行結果:
66666666…………

while 循環會一直執行下去,永不結束,成為“死循環”

  • while(0)
#include <stdio.h>
int main()
{
    while(0)
    {
        printf("6");
    }
    return 0;
}

運行結果:

運行結果為空,神木都不輸出.

while語句嵌套使用

  • 嵌套規則如下:
while(表達式1)
  while(表達式2)
    while(表達式3)
     …………
        while(表達式n)
        {
          語句段;
        }
  • 實例:打印五行數字1-5
#include<stdio.h>
int main()
{
    int i=1,j=1;
    while(i<=5)
    {
        while(j<=5)
        {
	        printf("%d ",j);
	        j++;
        }
        printf("\n");
        i++;
     }
    return 0;
}

執行結果:
1 2 3 4 5 
1 2 3 4 5 
1 2 3 4 5 
1 2 3 4 5 
1 2 3 4 5 

do-while語句的定義及應用

do-while語句和while語句執行規則相同,但do-while語句會首先執行循環體一次,然后判斷表達式,這也是和直到型語句的差別。

do-while循環的一般形式為:

do{
    語句塊
}while(表達式);

//補充
do-while循環與while循環的不同在於:它會先執行“語句塊”,然后再判斷表達式是否為真,
如果為真則繼續循環;如果為假,則終止循環。因此,do-while 循環至少要執行一次“語句塊”。

執行規則:
do-while語句首先執行循環體,然后判斷表達式是否為真(非0),若表達式為真,則繼續返回執行循環體,否則退出循環。

尤其需要注意的是:while(表達式);最后的分號;不能省略。

實例:

#include <stdio.h>
int main()
{
    int i=1, sum=0;
    do
    {
        sum+=i;
        i++;
    }while(i<=100);
    printf("%d\n", sum);
    return 0;
}

執行結果:
5050

和while語句類似的,我們對do-while中while中的表達式進行限制,分為兩種情況:

  • do-while(1)
#include <stdio.h>
int main()
{
    do
    {
        printf("6");
    }while(1);
    return 0;
}

運行結果:
66666666…………

do-while 循環會一直執行下去,永不結束,成為“死循環”

  • do-while(0)
#include <stdio.h>
int main()
{
    do
    {
        printf("6");
    }while(0);
    return 0;
}

運行結果:
6

從這里我們可以更明顯的感受到while語句,與do-while語句存在的差異。

do-while循環嵌套:

  • 一般格式為:
do
{
  do
  {
	do
        {
          循環體3;
          …………
        }while(表達式3)
        循環體2;
  } while (表達式2);
  循環體1;
} while (表達式1);
  • 實例:打印數字三角形
#include <stdio.h>
int main()
{
	int i=1,j;
	do
	{
	    j=1;
		do
		{
			printf("%d ",j);
			j++;
		}while( j<=i );
		printf("\n");
		i++;
	}while( i<=5 );
	
	return 0;
}

執行結果:
1 
1 2 
1 2 3 
1 2 3 4 
1 2 3 4 5 

for語句與while語句的相互轉化

 一般情況下,我們看到while與for具有類似的性質,都可以實現相同的循環功能,那while與for是不是可以相互轉化呢?答案是顯然的。

 轉換規則如下:

初始化
while(條件表達式)
{
  循環體
  標志變量修改
}

-------等價轉換線---------

for(初始化;條件;標志變量修改)
{
  循環體
}

我們舉一個栗子就可以理解這個轉換過程,我們不做過多解釋。

實現1-100的加法

  • while型
#include <stdio.h>
int main()
{
    int i, sum=0;
    i = 1;  //語句①
    while(i<=100 /*語句②*/ )
    {
        sum+=i;
        i++;  //語句③
    }
    printf("%d\n",sum);
    return 0;
}

語句①②③被放到了不同的地方,代碼結構較為松散,轉換為for后:

  • for型
#include <stdio.h>
int main()
{
    int i, sum=0;
    for(i=1/*語句①*/; i<=100/*語句②*/; i++/*語句③*/)
    {
        sum+=i;
    }
    printf("%d\n",sum);
    return 0;
}

for 循環中,語句①②③被集中到了一起,代碼結構更加清晰;

幾種循環的比較:

  1. for和while以及do while這3種循環都可以用來處理同一問題,一般情況下它們可以互相代替。
  1. while和do-while循環,是在while后面指定循環條件的,在循環體中應包含使循環趨於結束的語句(如i++,或i=i+1等)。

for循環可以在表達式3中包含使循環趨於結束的操作,甚至可以將循環體中的操作全部放到表達式3中。因此for語句的功能更強,凡用while循環能完成的,用for循環都能實現。

  1. 用while和do-while循環時,循環變量初始化的操作應在while和do-while語句之前完成。而for語句可以在表達式1中實現循環變量的初始化。

循環控制語句:break,continue

使用方法:

break;
continue;

后面沒有任何參數,且都有分號,不可省略.

break 語句,它不僅可以跳出“循環體”,還可以跳出 switch,break 也只能用於這兩種情況。

需要注意的有:

break 語句不能用於循環語句和 switch 語句之外的任何其他語句中。
循環的三種形式都可以用 break 跳出來,但 break 只能跳出一層循環。
當有多層循環嵌套的時候,break只能跳出“包裹”它的最里面的那一層循環,無法一次跳出所有循環。
在多層 switch 嵌套的程序中,break 也只能跳出其所在的距離它最近的 switch。但多層 switch 嵌套實在是少見。

而continue 的用法十分簡單,其作用為結束本次循環,即跳過循環體中下面尚未執行的語句,然后進行下一次是否執行循環的判定。

區別

continue 語句和 break 語句的區別為:

  • continue 語句只結束本次循環,而不是終止整個循環。
  • break 語句則是結束整個循環過程,不再判斷執行循環的條件是否成立。

此外,continue 只能在循環語句中使用,即只能在 for、while 和 do…while 中使用,除此之外 continue 不能在任何語句中使用。

所以,continue 不能在 switch 中使用,除非 switch 在循環體中。

此時 continue 表示的也是結束循環體的本次循環,跟 switch 也沒有關系。


參考文獻:
①《C語言從入門到精通》
for,while,do-while循環流程圖的的畫法總結


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM