第六章 初窺天機之循環結構程序設計

在生活中有許多事情需要反覆去做,才能達到預期的目的。比如學習的過程,我對陌生的知識通過學習,然後在經過反覆的複習才能長期的記住。這樣一個反覆的過程就是循環。

循環結構就是重複的執行某一過程,直到得出自己想要的結果或者達到循環結束的條件時,結束循環。循環結構能夠大大減少程序代碼的書寫量,提高代碼的利用率。

循環結構可以看成是一個條件判斷語句和一個向迴轉向語句的組合。循環結構組成三要素:循環變量、循環體、循環終止條件。

在C語言中,主要有四種循環結構,它們分別是:while循環、do-while循環、for循環以及goto循環。

 

6.1 循環結構

在C語言中,主要有四種循環結構,它們分別是:while循環、do-while循環、for循環以及goto循環。

爲了能夠大概理解循環結構,我們在本節將會簡單的介紹兩種最常用,最早接觸的循環結構,它們分別是:當型循環結構(相當於while循環)和直到型循環結構(相當於do-while循環)。無論是當型循環結構還是直到型循環結構,我們高中數學中就有所接觸,所以大家應該理解起來非常的容易。

 

6.1.1 當型循環結構

當型循環結構首先判斷是否滿足循環條件,如果滿足條件,則執行循環體中的語句。否則就是結束循環。

圖6.1 當型循環結構

如圖6.1(a)中,是當型循環結構的流程圖。程序執行時,首先判斷“循環條件”,如果“循環條件”爲真,則執行“循環體”。如果“循環條件”爲假,則結束“循環體”的執行或者根本就不執行“循環體”。

在圖6.1(b)中,是一個當型循環的實例流程圖。假設程序已經完成的基本的初始化工作,如i初始化爲1。首先就會判斷是不是“i<=100”爲真?也就是“1<=100”,如果爲真,則就會執行循環體“i++;”,顯然滿足循環條件,接着執行循環體。此時i自加以後變成2,再判斷“2<=100”?顯然仍然滿足條件。...我們依次經過100次循環,此時i值等於100,然後我們判斷是否“100<=100”?顯然這個也滿足題意,執行循環體“i++;”。i就變成101,接着進行判斷是否“101<=100”?很明顯爲假。所以結束程序的循環,順序執行循環體後面的語句。舉一個生活中的實例。

 

6.1.2 直到型循環結構

直到型循環結構首先執行的是循環體中的語句,在判斷循環條件。如果滿足循環條件,再次執行循環體中的語句,如果不滿足循環條件,則結束循環。

圖6.2 直到型循環結構

如圖6.2(a)中,是直到型循環結構的流程圖。程序執行時,首先執行“循環體”,然後判斷“循環條件”,如果“循環條件”爲真,則再次執行“循環體”。如果“循環條件”爲假,則結束“循環體”的執行。

在圖6.2(b)中,是一個直到型循環的實例流程圖。假設程序已經完成的基本的初始化工作,如i初始化爲1。首先就會會執行循環體“i++;”,然後再判斷是不是“i<=100”爲真?也就是“1<=100”,如果爲真,則就會繼續執行循環體“i++;”,否則結束。顯然滿足循環條件,接着執行循環體“i++;”。此時i自加以後變成2,再判斷“2<=100”?顯然仍然滿足條件。...我們依次經過100次循環,此時i值等於100,然後我們判斷是否“100<=100”?顯然這個也滿足題意,仍然執行循環體“i++;”。i就變成101,接着進行判斷是否“101<=100”?很明顯爲假。所以結束程序的循環,順序執行循環體後面的語句。

在生活中這樣的例子也是無處不在,比如:當一個男生突然有一天看到了一個心儀的女生,希望這個漂亮的女生能夠做他的女朋友。於是,就開始的寫他的第一封情書(循環體),可是這個女生不喜歡這個男生,所以直接拒絕了這個男生(循環條件)。但是,這個男生髮現他真的喜歡上了這個女生,希望每天都能夠見到這個女生,如果哪一天見不到她,就會茶不思飯不想,甚至還天天夢見她。爲了追到她,男生寫了第二封,第三封情書,,,直到第81封的時候,這個女孩子終於心動了,爲這個男生的執着所打動。最後他們幸福的在一起了。從這個例子中我們就會看到“循環體”就是“情書”,循環結束條件就是寫到“第81封”的時候結束。小夥伴你是怎麼最女生的呢?哈哈。

 

6.2 while循環結構

6.2.1 while循環結構基本介紹

while循環結構首先判斷是否滿足循環條件,如果滿足條件,則執行循環體中的語句。否則就是結束循環。

while循環的基本語法:

while(表達式) 循環體語句

while循環在執行的過程中,首先判斷while後面的“表達式”,如果表達式始終爲真,則重複執行循環體。直到表達式爲假時,才結束while循環的執行。就是說while循環是先執行表達式的判斷,然後根據判斷結果來選擇是否執行循環體。如圖4.1所示,爲while循環的流程圖。但是在使用的過程中,我們需要注意三點:

(1) while循環中的“表達式”一般爲關係表達式或者邏輯表達式,當表達式爲真時,執行“循環體語句”。

(2) 如果循環體語句兩個及兩個以上要用{}(花括號)括起來。

即:

while(表達式)

{

    循環體語句1;

    循環體語句2;

}

比如:

int a = 1;

while(a <= 10)

{

    printf(“%d\n”, a);

    a++;

}

同時兩個及兩個以上組成的循環體語句,又稱爲複合體語句。還需要注意在寫程序時程序需要初始化,否則將會出現不可預知的錯誤。

(3) 在書寫循環時,應儘量保證循環體能夠正常結束。除非有特殊要求(比如開機後的操作系統就是一個死循環)。

圖6.3 while循環流程圖

 

例6.1】求1+2+3+…+100的值。

解題思路:我們可以通過循環變量num來控制1~100數值的變化,並初始化爲1。然後設定循環結束條件爲循環變量小於等於100,再定義另一變量sum作爲統計變量的累加和。

編寫代碼:

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

運行結果:

1+2+…+100 = 5050

Press any key to continue

 

程序分析:程序第4行,定義變量num並初始化爲1。第5~9行爲程序核心代碼,首先判斷num是不是小於100。由於num初始化爲1,所以小於100,滿足條件執行循環體。第7行又等價於“sum = sum + num;”,表示sum加上num的值賦給sum。第8行等價於“num = num + 1”,表示num的值加上1,再賦值給num。得出的num值再返回第5行,判斷num是否小於100,如果小於就繼續執行循環。否則跳出while循環執行第10行,輸出結果。

 

此處還可以添加程序實例。實例太少。儘量多的添加代碼。while循環的代碼。

6.2.2 while循環嵌套

在實際編程中,我們會遇到一層循環中還有一層或多層循環,那麼這樣多重循環組成的結構成爲循環嵌套。

while循環嵌套的基本語法:

外層while循環在執行的過程中,首先判斷while後面的“表達式”,如果表達式始終爲真,則重複執行循環體。直到表達式爲假時,才結束while循環的執行。同理,當外層表達式爲真時,就會執行循環體,就是說內層while循環就開始執行了。具體執行規則和方式與執行外層while循環一樣。如圖6.4所示,爲兩層while循環嵌套的流程圖。但是在使用的過程中,我們需要注意與單層循環類似,此處不再贅述。建議無論多層還是一層循環嵌套,都應該用{}把循環體中要執行的語句括起來,這樣會給編程提供很大的便利。

圖6.4 兩層while循環嵌套流程圖

 

比如:

int a = 1, b = 1;
int sum = 0;
while(a <= 5)
{
	b = 1;
	while(b <= 50)
	{
		sum += b;
		b++;
	}
	a++;
}
printf(“%d\n”, sum);

該段程序實現的功能等價於(1+2+…+50)*5的最終結果。

 

例6.2】輸出九九乘法口訣。

解題思路:

九九乘法口訣表如下:

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

由表我們看出,在九九乘法口訣表的同一列中被乘數保持不變,乘數依次加1。在不同的列中,從左向右被乘數依次增加1,同時列中乘式個數依次減1。並且被乘數小於等於乘數。那麼我們就可以定義兩個變量:一個變量表示被乘數,作用於內層循環。一個變量表示乘數,作用與外層循環。外層變量共循環9次,內層變量小於等於外層變量。具體代碼如下。

編寫程序:

#include <stdio.h>
int main()
{
	int i=1,j=1;
	while (i <= 9)/*外層循環*/
	{
		j=1;
		while(j <= i)/*內層循環,內層循環變量小於外層循環變量*/
		{
			printf("%d×%d=%2d    ", j,i,i*j);/*輸出乘法口訣*/
			j++;//每一次循環變量加1
		}
		i++;
		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

Press any key to continue

 

程序分析:第5~15行爲程序的核心代碼。本程序共有兩個while循環,且屬於while循環的嵌套。外層while循環爲乘數,內層while循環爲被乘數。外層循環執行一次,內層循環就會執行一個循環。

此處while循環嵌套的代碼過少,添加實例。

6.3 do-while循環結構

6.3.1 do-while循環結構基本介紹

do-while循環結構是while循環的變體。do-while循環首先執行循環中的語句,然後判斷是否滿足循環條件,如果滿足循環執行循環中的語句,直到不滿足循環條件,則結束循環。

do-while循環的基本語法:

do

    循環體語句;

while(表達式);

do-while循環在執行的過程中,首先執行循環體,然後判斷while後面的“表達式”是否爲真,如果表達式始終爲真,則重複執行循環體。直到表達式爲假時,才結束while循環的執行。就是說while循環是先執行循環體語句,然後進行表達式的判斷,根據判斷結果來選擇是否重複執行循環體。如圖6.5所示,爲do-while循環的流程圖。但是在使用的過程中,我們需要注意兩點:

  1. do-while語句的特點是“先執行,後判斷”。即無論“表達式”的初始值爲真還是爲假,循環體都會先被執行一次。
  2. 如果do-while循環中,有多條語句組成,必須用{}括起來,形成複合語句。

複合語句的語法:

do

{

    循環體語句1;

    循環體語句2;

}while(表達式);

比如:

int a = 1;

do

{

    printf(“%d\n”, a);

    a++;

}while(a <= 100);

即do-while循環裏面的語句全部用{}括起來。

圖6.5 do-while循環流程圖

 

例6.3】求1+2+3+…+100的值。

解題思路:我們可以通過循環變量num來控制1~100數值的變化,並初始化爲1。然後設定循環結束條件爲循環變量小於等於100,再定義另一變量sum作爲統計變量的累加和。前提是我們知道程序至少會執行一次。

編寫程序:

#include <stdio.h>
int main()
{
	int num = 1, sum = 0;
	do/*do-while*/
	{
		sum += num;//用sum統計100以內的和
		num++;//每一次變量加1
	}while (num <= 100);
	printf("1+2+…+100 = %d\n", sum);//輸出結果
	return 0;
}

運行結果:

1+2+…+100 = 5050

Press any key to continue

 

程序分析:程序中用num表示要加的數字,比如:1,2,3,...,100,這些數。用sum統計這些數的值。程序第9行while後面的括號是循環的判斷語句。判斷語句成立繼續執行循環,如果判斷語句不成立,則結束循環的執行,轉到程序第10行繼續執行。

 

此處添加代碼。do-while的代碼。

 

6.3.2 do-while循環嵌套

如同while循環嵌套一樣,do-while循環也也可以實現循環的嵌套。如下。

do-while循環嵌套的基本語法:

外層do-while循環每執行一次,內層就會執行一個完整的循環。比如:

int a = 1, b = 1;

int sum = 0;

do

{

    b = 1;

    do

    {

        sum += b;

        b++;

    }while(b <= 50);

    a++;

}while(a <= 5);

當外層循環中a每加一次,內層循環b就會從1加到50,做一個50次的循環。

如圖6.6所示,爲兩層do-while循環嵌套的流程圖。但是在使用的過程中,我們需要注意與while循環類似,建議爲每一層循環,都用{}把循環體中要執行的語句括起來,這樣會給編程提供很大的便利,提高程序的可讀性。

圖6.6 兩層的do-while循環嵌套流程圖

 

例6.4】輸出九九乘法口訣。

解題思路:結合程序【例6.2】的分析,我們現在要給寫成do-while循環的嵌套。首先do-while循環是先執行循環體語句,然後在進行判斷,並且外層循環執行一次,內層就會執行一個循環。所以我們可以把外層循環變量作爲被乘數,內層循環變量作爲乘數。

編寫代碼:

#include <stdio.h>
int main()
{
	int i=1,j=1;
	do
	{
		j=1;
		do
		{
			printf("%d×%d=%2d    ", j,i,i*j);/*輸出乘法口訣*/
			j++;
		}while(j <= i);/*內層循環*/
		i++;
		printf("\n");
	}while (i <= 9);/*外層循環*/
	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

Press any key to continue

 

程序分析:程序並不是非常複雜,和【例6.2】類似,大家可以此作爲參考。

 

在程序的實際操作中我們會發現while循環和do-while循環的區別,我們首先看下面一個分別用while循環和do-while循環寫程序事例:

程序1:

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

運行結果:

Press any key to continue

 

程序2:

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

運行結果:

5

Press any key to continue

 

通過這兩個程序運行結果的對比,我們發現while循環沒有輸出結果,而do-while循環卻輸出了一個結果:5。因爲什麼呢?就是因爲while循環和do-while循環他們的運行特性所決定的。while循環是先判斷,再執行。所以a=5時,在while循環的表達式中執行判斷“a<5”是否爲真,因爲爲假,所以便不會執行循環體。而do-while循環由於先執行循環體,然後在判斷表達式,這就決定了會先輸出一個5,再a++的值爲6,然後在判斷表達式“a<5”是否爲真,即“6<5”是否爲真,顯然爲假。所以結束do-while循環的執行。

 

6.4 for循環結構

6.4.1 for循環結構基本介紹

for循環語句是我最喜歡使用的循環語句,同時也是C語言中使用頻率頻率最高的循環語句。for循環語句又稱技術循環語句。for循環比while循環語句和do-while循環語句都要靈活,是一種功能更強、更常用的循環語句。

for循環的基本語法:

for(表達式1; 表達式2; 表達式3)

{

    循環體語句;

}

各個表達式的作用:

表達式1:設置初始條件(比如i=1),初始條件可以是零個、一個或多個等,當變量是多個時,用“,”分隔,比如:

for(i=0,sum=1,b=2  ; ... ; ... )

{}

表達式1在for循環中只執行一次,並且是for循環的第一個執行表達式。

表達式2:是for循環的判斷表達式,用來判斷是否繼續執行for循環,還是結束for循環的執行。每次執行循環體前都需要先判斷表達式的真假,以此決定for循環的執行方向。比如:

for(i=0,sum=1,b=2; i<10 ; ... )

{}

for循環中執行完“表達式1”,就會執行“表達式2”。

表達式3:循環結構的控制。可以作爲循環次數控制,比如:

for(i=0,sum=1,b=2; i<10 ; i++ )

{}

“表達式3”會在“表達式1”,“表達式2”,“循環題語句”執行之後執行。

for循環執行順序的流程圖,如圖6.7所示。

圖6.7 for循環流程圖

 

其執行順序爲:

  1. 執行“表達式1”。
  2. 執行“表達式2”,“表達式2”爲判斷語句。如果“表達式2”爲真,執行“循環體語句”。否則結束for循環語句。
  3. 執行“表達式3”。
  4. 轉到(2)中,以此循環執行for語句。
  5. 結束for循環的執行,順序執行for循環後面的語句。

按上述步驟依次執行循環結構直到程序滿足結束條件,或者循環次數就會結束for循環的執行。

for循環一般形式爲如下:

for( 循環變量賦初值 ; 循環條件 ; 循環變量增值 )

{

    循環體語句;

}

如圖6.8 爲for循環一般形式的流程圖。

圖6.8 for循環一般形式流程圖

 

比如:

for(i = 1 , sum = 0 ; i <= 100 ; i++ )

{

    sum += i;

}

其中:

(1) “i=1”表示:i爲循環變量,並賦初值爲1;

(2) “i<=100”表示:當i值小於等於100爲真時,執行for循環。否則結束for 循環。即i的循環次數爲100次。

(3) “sum += i”表示:sum每一次加上i值,然後在賦值給sum,等價於sum=sum+i。 也就是說,該for循環的功能就是實現1~100的累加和。

(4) “i++”表示:控制循環變量的次數,同時有參與循環體語句的運算。“i++” 表示i加上1,然後賦值給i,等價於i=i+1;

總的來說,該程序實現的功能就是計算1+2+3+…+100的累加和。

那麼,該for循環還可以變形成爲其他結構,比如以下:

  • 把初始化的i=1寫在for循環的前面,即讓“表達式1”省略,但for循環中不能省略“表達式1”後面的“;”。例如:

i = 1;

sum = 0;

for(  ; i <= 100 ; i++ )/*此處省略“表達式1”*/

{

    sum += i;

}

  • 讓for循環中的“表達式2”省略,同樣“表達式2”後面的分號不能省略。如果“表達式2”省略,則表示for循環成爲永真式。比如:

for(i = 1 , sum = 0 ;  ; i++ )/*此處省略“表達式2”*/

{

    sum += i;

}

如果內存夠大程序會一直執行下去。當然,我們也可以用其他的方式讓for循環結束執行,比如break語句、exit語句、return語句等,我們將在後面的章節中介紹。

  • 如果我們不寫“循環體語句”而是把相應的實現功能寫到“表達式3”中,那麼就會有如下情況:

for(i = 1, sum = 0 ; i <= 100 ; i++ )/*此處省略“循環體語句”*/

{

}

爲了是程序可以完整執行,則進一步可以改寫成:

for(i = 1 ; i <= 100 ; sum += i , i++ );

  • 當然我們也可以省略“表達式3”,如果省略“表達式3”,將會有如下形式:

for( i = 1 , sum = 0 ; i <= 100 ;  )/*此處省略“表達式3”*/

{

    sum += i;

}

爲了是程序可以完整執行,則進一步可以改寫成:

for(i = 1 ; i <= 100 ;  )

{

    sum += i;/*“循環體語句”*/

    i++;/*實現“表達式3”的功能*/

}

 

以for循環的基本語法爲例,分別轉換成爲對應的while循環和do-while循環。

(1) for循環轉換爲while循環:

表達式1;

while (表達式2)

{

循環體語句;

表達式3;

}

注:二者是無條件等價,即可以實現無縫轉換。

  • for循環轉換爲do-while循環:

表達式1;

do

{

   循環體語句;

   表達式3;

}while(表達式2);

注:二者是有條件轉換,即for循環必須至少執行一次,纔可以轉換成爲do-while循環。這由do-while循環的性質所決定。

 

 

例6.5】求1+2+3+…+100的值。

解題思路:我們可以通過循環變量num來控制1~100數值的變化,並初始化爲1。然後設定循環結束條件爲循環變量小於等於100,再定義另一變量sum作爲統計變量的累加和。

編寫程序:

#include <stdio.h>
int main()
{
	int num, sum;
	for(num = 1, sum = 0; num <= 100; num++)/*for循環*/
	{
		sum += num;//實現結果累加
	}
	printf("1+2+…+100 = %d\n", sum);//輸出結果
	return 0;
}

運行結果:

1+2+…+100 = 5050

Press any key to continue

 

程序分析:大家會發現其實這個程序和【例6.1】以及【例6.3】一樣,都是爲了解決100以內的和的問題。此處不再贅述。

 

6.4.2 for循環嵌套

如同while循環和do-while循環的嵌套一樣,for循環也也可以實現循環的嵌套。如下。

for循環嵌套的基本語法:

外層for循環每執行一次,內層就會執行一個完整的循環。比如:

int a = 1, b = 1;

int sum = 0;

for(a=1 ; a<=50 ; a++)

{

for( b=1 ; b<=50 ; b++)

{

    sum += b;

}

}

當外層循環中a每加一次,內層循環b就會從1加到50,做一個50次的循環。

如圖6.9所示,爲兩層for循環嵌套的流程圖。但是在使用的過程中,我們需要注意與while循環或者do-while循環類似,建議爲每一層循環,都用{}把循環體中要執行的語句括起來,這樣會給編程提供很大的便利,提高程序的可讀性。

圖6.9 兩層for循環嵌套流程圖

 

例6.6】輸出九九乘法口訣。

解題思路:結合程序【例6.2】的分析,我們現在要給寫成for循環的嵌套。首先for循環需要循環變量初始化,然後在進行判斷,並且外層循環執行一次,內層就會執行一個循環。所以我們可以把外層循環變量作爲被乘數,內層循環變量作爲乘數。每執行一個內層循環,循環變量都會被初始化爲1。

編程程序:

#include <stdio.h>
#define N 9			/*宏定義,定義N代表數字9*/
main()
{
	int i,j;
	for(i=1; i<=N; i++)/*外層循環*/
	{
		for(j=1; j<=i; j++)/*內層循環*/
		{
			printf("%d×%d=%2d    ", j,i,i*j);/*輸出乘法口訣*/
		}
		printf("\n");
	}
}

運行結果:

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

Press any key to continue

 

程序分析:程序第2行的“#define N 9”爲宏定義,就是說用N代替數值9,即N的值就是9。第10行在輸出時會加上一些空格,是爲了保證輸出格式的美觀。第12行是換行,爲了輸出成階梯狀的格式。

注意:

#define的三個作用:

  1. 定義標識,標示有效範圍爲整個程序。
  2. 定義常數,比如:#define N 9,即N代表9。
  3. 定義函數,比如:#define obtainMax(a,b) ((a)>(b)?(a):(b))。

例6.7】判斷200以內的正整數有多少素數,並輸出所有的素數。

解題思路:素數只能被1和自身整除的正整數,1不是素數。要判斷一個正整數是否爲素數,需要檢查該數是否能被1和自身以外的其他數整除,即判斷正整數n能否被2~n-1之間的數整除,如果能被其中任意一個數整除,那麼n不是素數,否則n就是素數。

在程序中可以用求餘%來表示能否整除。即n%(2~n-1)進行依次判斷。但是在數學中還有一個更加高效的方法,就是區間變成[2, sqrt(n)]。因爲如果一個數不是素數,那麼它一定可以由兩個自然數相乘得到,其中一個大於等於它的平方根,一個小於等於它的平方根。

編寫程序:

#include <stdio.h>
int main()
{
	int i,j,k=0;
	printf("200以內的素數有:\n");
	for(i=2;i<=200;i++)/*列舉2~200中所有的數*/
	{
		for(j=2;j<=i;j++)/*判斷要求數字是否爲可能爲素數*/
			if(i%j==0) break;
		if(j>=i)/*如果j>=i,表明是素數*/
		{
			printf("%3d ",i);
			k++;
			if(k%5==0) printf("\n");//按照每行輸出5個形式輸出結果。
		}
	}
	printf("\n");
}

運行結果:

200之間的素數有:

  2   3   5   7  11

 13  17  19  23  29

 31  37  41  43  47

 53  59  61  67  71

 73  79  83  89  97

101 103 107 109 113

127 131 137 139 149

151 157 163 167 173

179 181 191 193 197

199

Press any key to continue

 

程序分析:程序第9行如果i去j的餘數爲0,表示i可能是素數也可能不是素數,因爲如果成多倍整除就不是素數。如果倍數爲一,表示爲素數。所以就有第10行判斷被除數與除數是否相等。相等就是素數。否則,反之。

 

添加代碼。for循環嵌套代碼。

6.5 三種循環的相互嵌套

在我們講解while循環、do-while循環和for循環的時候,我們都相應的介紹的它們各自的循環嵌套格式。但是它們嵌套是它們自己的類型。那麼是不是可以while循環嵌套do-while循環呢?或者do-while循環嵌套for循環呢?再或者for循環嵌套while循環呢?答案是肯定的。下面我們將介紹三種循環間的嵌套。

以上6中循環分別是while循環嵌套do-while循環和for循環,如(1)、(2)。do-while循環中嵌套while循環和for循環,如(3)、(4)。for循環中嵌套while循環和do-while循環,如(5)、(6)。此處我們還用九九乘法口訣來實現,輸出結果與之前對應例題的效果一樣。

  • while循環中嵌套do-while循環。
int i=1,j=1;
while (i <= 9)/*外層循環*/
{
	j=1;
	do
	{
		printf("%d×%d=%2d    ", j,i,i*j);/*輸出乘法口訣*/
		j++;
	}while(j <= i);/*內層循環*/
	i++;
	printf("\n");
}

 

  • while循環中嵌套for循環。
int i=1,j=1;
while (i <= 9)/*外層循環*/
{
	j=1;
	for(j=1; j<=i; j++)/*內層循環*/
	{
		printf("%d×%d=%2d    ", j,i,i*j);/*輸出乘法口訣*/
	}
	i++;
	printf("\n");
}

 

  • do-while循環中嵌套while循環。
int i=1,j=1;
do
{
	j=1;
	while(j <= i)/*內層循環*/
	{
		printf("%d×%d=%2d    ", j,i,i*j);/*輸出乘法口訣*/
		j++;
	}
	i++;
	printf("\n");
}while (i <= 9);/*外層循環*/

 

  • do-while循環中嵌套for循環。
int i=1,j=1;
do
{
	for(j=1; j<=i; j++)/*內層循環*/
	{
		printf("%d×%d=%2d    ", j,i,i*j);/*輸出乘法口訣*/
	}
	i++;
	printf("\n");
}while (i <= 9);/*外層循環*/

 

  • for循環中嵌套while循環。
int i,j;
for(i=1; i<=9; i++)/*外層循環*/
{
	j=1;
	while(j <= i)/*內層循環*/
	{
		printf("%d×%d=%2d    ", j,i,i*j);/*輸出乘法口訣*/
		j++;
	}
	printf("\n");
}

 

  • for循環中嵌套do-while循環。
int i,j;
for(i=1; i<=9; i++)/*外層循環*/
{
	j=1;
	do
	{
		printf("%d×%d=%2d    ", j,i,i*j);/*輸出乘法口訣*/
		j++;
	}while(j <= i);/*內層循環*/
	printf("\n");
}

 

 

6.6 goto循環結構

6.6.1 goto語句循環基本介紹

goto語句又稱無條件轉移語句,其跳轉方向既可以是前方,又可以是後方。goto語句是一種不建議使用的跳轉語句,因爲如果goto語句的使用會造成程序流程的混亂,是理解和調試都產生困難。

goto語句的基本語法:

goto 語句標號;

C語言中不限制程序中使用標號的次數,但各標號不得重名。goto語句的語義是改變程序流向,轉去執行語句標號所標識的語句。

goto語句通常與條件語句配合使用。可用來實現條件轉移、構成循環、跳出循環等功能。

比如:

int i;
i = 1;
label:
if( i <= 100)
{
	printf("%d\n", i);
	i++;
	goto label;
}

我們已經介紹了goto語句的基本語法:goto 語句標號;。如上例第8行所示,“goto label;”中的label就是語句標號。而第3行的label就是goto語句要跳轉的地方。也就是說執行完第8行的“goto label;”會跳轉到第2行的“label:”處,再順序執行。語句標號就是指明goto語句要跳轉到的位置。如圖6.10所示爲該實例的流程圖。

圖6.10 goto語句流程圖

整個程序的執行步驟如下:

  1. 程序i賦初值。
  2. 判斷i是否小於等於100,如果是執行(3),如果不是執行(5)。
  3. 輸出i的值,並且i++。
  4. 無條件轉移到(2)。
  5. 結束goto語句的執行,順序下面的語句。

 

 

例6.8】求1+2+3+…+100的值。

解題思路:我們可以通過循環變量num來控制1~100數值的變化,並初始化爲1。然後設定循環結束條件爲循環變量小於等於100,再定義另一變量sum作爲統計變量的累加和。

編寫程序:

#include <stdio.h>
int main()
{
	int num, sum;
	num = 1, sum = 0;
lable://標籤位置
	if( num <= 100)
	{
		sum += num;//統計100以內的和
		num++;//數值每次加1
		goto lable;//跳轉到lable標籤的位置。
	}
	printf("1+2+…+100 = %d\n", sum); 
	return 0;
}

運行結果:

1+2+…+100 = 5050

Press any key to continue

 

程序分析:事實上,goto語句在C語言中並不提倡使用,因爲過多goto語句的使用會導致程序結構的混亂,爲後期的維護帶來極大地不便。此處講解goto語句,僅共大家瞭解。

 

 

6.6.2 goto語句嵌套

同其他三種循環一樣,goto也有自己的循環嵌套。當然由於goto語句的嵌套沒有固定的位置(既可以向前,又可以向後),所以很難書說明goto語句的嵌套。但是由於其形式同單個goto語句一樣。所以理解起來也並非難事。接下來我們將通過具體的實例介紹goto語句的嵌套。

例6.9】輸出九九乘法口訣。

解題思路:結合程序【例6.2】的分析,我們現在給出寫成goto語句的循環嵌套。goto語句通過其後面的標籤,用於標記出要跳轉的位置。

編寫代碼:

#include <stdio.h>
#define N 9
int main()
{
	int i,j;
	i=1;
label1://外層標籤的位置
	if(i<=N)
	{
		j=1;
	label2://內層標籤的位置
		if(j<=i)
		{
			printf("%d×%d=%2d    ", j,i,i*j);/*輸出乘法口訣*/
			j++;
			goto label2;/*內層循環*/
		}
		printf("\n");
		i++;
		goto label1;/*外層循環*/
	}
}

運行結果:

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

Press any key to continue

 

程序分析:詳情請看程內部註釋。

 

 

6.7 break與continue

在程序的運行過程中,如果我們想要提前結束程序的運行時,怎麼辦呢?當然C語言爲我們準備了兩種改變程序運行方向的語句:break和continue語句。break語句的作用是結束有效範圍內的整個循環。continue語句的作用是結束本次循環,執行下一次循環。下面就讓我們詳細的瞭解這兩者詳細信息,以及他們的聯繫與區別吧!!!

 

6.7.1 break語句的介紹

在循環體中通過break語句,能夠提前結束循環體的執行,轉去執行循環外的語句。

break語句的基本語法:

break;

其作用就是跳出循環體,去執行循環體之外的語句。如圖6.11所示,爲break的流程圖。

比如:

for(i = 1 , sum = 0 ; i <= 100 ; i++ )
{
	sum += i;
	if(sum > 100)
	{
		break;
	}
}
printf(“%d\n”, sum);

該程序是求1~100的累加和,但是如果累加和大於100,那麼程序就會結束。說白了,就是計算小於100的累加和。如圖6.12所示,爲改程序的流程圖。

圖6.11 break語句流程圖

 

圖6.12 break語句程序流程圖

 

注意:

  1. break語句不能用於循環語句和switch語句以外的其他任何語句中。常與循環語句、switch或if語句配合使用。
  2. 一個break語句只向外跳一層,如果是多層循環的嵌套,那麼需要按照嵌套的次序逐步用break跳出循環。
  3. break語句應用在switch中,只跳出switch語句。
  4. 總的來說break語句結束是按照就近原則,結束當前循環。

例6.10

 

 

6.7.2 continue語句的介紹

我們已經知道break語句是結束當前循環的執行,可是如果我們想要只是結束當前一次循環,而不是整個循環的結束呢?那麼continue語句應運而生。

continue語句的基本語法:

continue;

其作用就是就是結束本次循環,執行下一次循環。如圖6.13所示,爲break的流程圖。

比如:

for(i = 1 ; i <= 100 ; i++ )
{
	if(0 == i%2)
	{
		continue;
	}
	printf("%d\n", i);
}

該程序是輸出100以內所有的奇數。如圖6.14的流程圖所示。

圖6.13 continue語句流程圖
圖6.14 continue語句程序流程圖

 

例6.11】100以內奇數累加和:1+3+…+99 = ?。

解題思路:

我們有兩種方法來求:

方法1:我們用變量i表示從1到100的累加變量,用sum表示累加和。判斷是否i%2的餘數是否爲0,如果爲零,表示i爲偶數,就用continue語句結束該次循環,執行下條循環。否則i就是奇數,就讓sum加上對應的讓sum加上i。

方法2:我們還是設置變量i從1到100的累加變量,但是i的增值變成了2,即i=i+2,就是i值的變化範圍是1,3,5,…,99。然後在定義sum表示累加和,這樣直接和sum累加就行。

注:我們此次只介紹方法1,方法2留給同學們自己去思考。

編寫代碼:

#include <stdio.h>
int main()
{
	int i,sum;
	for(i = 1 , sum = 0 ; i <= 100 ; i++ )
	{
		if(0 == i%2)//i取2的餘數爲0表示i爲偶數,否則爲奇數。
		{
			continue;
		}
		sum += i;
	}
	printf("1+3+…+99 = %d\n", sum);
	return 0;
}

運行結果:

1+3+…+99 = 2500

Press any key to continue

 

程序分析:程序較簡單,不在做過多解釋。

注意:

1. continue語句不能用於循環語句和switch語句以外的其他任何語句中。常與循環語句、switch或if語句配合使用。

2. 在一個循環體中,一個continue語句只終止本次循環的執行,即跳過循環體語句中continue語句後面的尚未執行的語句,接着進行下次判斷。

 

6.7.3 break語句與continue語句的聯繫與區別

 

6.7 沙場點兵

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章