天天看點

【C語言入門教程】3.4 循環控制語句

循環結構又稱重複結構,是程式的 3 種基本結構之一。它反複執行循環體内的代碼,解決需要大量重複處理的問題。循環結構由循環控制語句實作,其中内建有條件控制語句,用來判讀是否繼續執行循環操作。C 語言提供了 while 語句、do-while 語句、for 語句 3 種基本的循環控制語句,并且可以互相嵌套使用。

3.4.1 while 語句

while 語句是“當”型循環控制語句,即在條件滿足時執行循環體,否則跳過或跳出循環體。while 語句的一般形式為:

while (條件表達式) { 循環體; }

如下例所示,求階乘 n! 的結果:

int n = 1, p;			// 聲明整型變量 n 和 p,n 用于控制步進,p 用于儲存操作數
double s = 1;			// 聲明雙精度變量 s, s用于儲存計算結果
printf("請輸入操作數 (1 - 170):");	// 輸出操作提示資訊
scanf("%d", &p);		// 擷取操作數,儲存到變量 p 中
while (n <= p)		   // 當步進值不大于操作數時,執行循環體
{
	s *= n++;			// 将上一次的計算結果 s 與 步長值 n 相乘,并儲存新的計算結果到 s,計算完成後步進值 n 自增
}

printf("\n階乘 n = %d 的結果為:%fd \n", p, s);	// 輸出操作結果      

上例使用循環控制語句進行階乘操作,while語句中的表達式用于判斷目前階乘的步進值是否大于輸入的操作數。如果不大于則繼續進行運算,否則結束循環。

提示:階乘(factorial)是基斯頓.卡曼(1760 - 1826)于1808年發明的運算符号。階乘指從 1 乘以 2 乘以 3 乘以 4 一直乘到所要求的數。例如操作數是 4,則階乘式是 1 x 2 x 3 x4,得到的結果是 24,24就是 4 的階乘。階乘的計算會産生相當巨大的結果,在 C 語言的基本資料類型中字長最大的 double 型,也隻能儲存 170!的運算結果。當然,有很多方法可以儲存更大的階乘結果,有興趣的可以探索這一問題。

3.4.2 do-while 語句

在 C語言中,“直到” 型循環是 do-while 語句,一般的形式為:

do { 循環體 } while { 條件表達式 }

與 while 語句的差別是,while 是先判讀條件表達式再去執行循環體,而 do-whie 語句是先執行循環體再判讀條件表達式。也就是說,do-while 語句會首先将循環體執行一次,再判斷是否應該結束循環。例如計算 sin(x) 的值算法是“x - x3/3! + x5/5! - x7/7(......)”直到最後一項小于 1e-7 時為止,可用下例代碼描述:

#include <stuio.h>
#include <math.h>				// 加入數學函數庫,以提供幂運算函數 fabs()

int main()
{
	double s, t, x;				// 定義雙精度型變量 s、t、x,其中 s 儲存計算結果,t 表示下一項的結果,x 表示操作數

	int n;						// n表示公式中的 幂
	printf("請輸入 x 的值:");
	scanf("%lf", &x);			// 擷取操作數
	t = x;						// 使 t 的值等于 x,得到公式中的第一項的值
	n = 1;						// 初始化幂數 n 為 1
 	s = x;						// 将第一項的結果儲存到結果 s 中
	
	do
	{
		n += 2;
		t *= (-x * x) / ((float)(n) - 1) / (float) (n);
		s += t;
	}
	while (fabs(t) >= le-7);
	
	printf("\nsin(%f) = %lf\n", x, s);

	return 0;
}      

上例中,使用循環控制語句依次将公式中的每一項加入結果中,從上一項推算目前項的結果隻用将上一項乘以因子(x2)/((n-1) * n),即代碼第 16 行所示。函數fabs()由頭檔案 math.h提供,作用是取絕對值。當輸入 x 的值為 1.5753時,運算結果為 0.999 990。

3.4.3 for 語句

for 語句使用于可預知執行次數的循環控制結構,是 C 語言中最常用的循環控制語句。for 語句的一般形式為:

for (<表達式1>; <表達式2>; <表達式3>) { 循環體 }

表達式1 用于為控制變量賦初始值,表達式2用于放置循環控制條件的邏輯表達式,表達式3用于改變變量的值。這種結構能明确地展現循環控制結構中的 3 個重要組成部分,即控制變量的初始值、循環條件 和 控制變量 的改變。如計算自然數數列 1 至 n 的平方和,可用下列代碼描述:

int i, p;
double s = 0;
printf("請輸入操作數:\n");
scanf("%d", &p);

for (i = 1; i <= p; i++)
{
	s += (double) i * (double) i;
}

printf("自然數 1 至 %d 平方和為:%lf\n", p, s);      

for語句的 3個表達式都可以省略,或者放置在 for 語句的參數集合外,但不能省略表達式之間的分号,否則會造成文法錯誤。

注意:在編寫循環結構的程式時,如果循環控制條件不能有效地結束,就會出現死循環,這是程式員經常會碰到的問題。含有死循環的代碼能被編譯器編譯,但運作該程式會造成循環體無休止地被執行,消耗系統資源,嚴重的會造成系統當機。Linux系統針對死循環有良好的控制機制,不會讓一個程序無休止地占據所有CPU資源,進而避免當機現象。當然,死循環在某些情況下存在是合理的,例如硬體驅動程式,通信程式和裝置控制程式中,都需要用死循環反複無休止地處理某些問題。while(1) 和 for(;;) 常被生成死循環。

3.4.4 break 與 continue 語句

如果需要在循環體的執行過程中結束某一輪循環,或者直接跳出循環,可以使用 break 或  continue 語句。

break 語句的作用是立即結束目前循環并跳出循環體。下例用一個有趣的計算題說明該語句的使用方法,一隻蝸牛順着葡萄架向上爬,葡萄架高 11 米,蝸牛每天白天可以向上爬 3 米,但晚上會滑下來 1 米,問該蝸牛幾天能夠爬到葡萄架的頂端,程式代碼如下:

int i = 1, s = 0;			// 定義變量 i 和 s,表示天數,s 表示已爬上的高度
const int h = 11;			// 定義常量 h,h 表示總高
const int up_move = 3;		// 定義常量 up_move,up_move 表示每天爬上的高度
const int down_move = 1;	// 定義常量 down_move,down_move 表示每天滑下的高度

while (s <= h)				// 當 s 不大于 h 時,執行循環體
{
	s += up_move;			// 将已爬上的高度加上當天爬上的高度
	if (s >= h)		 	   // 判讀已爬上的高度是否不小于總高度
	{
		break;				// 結束目前循環,并跳出循環體
	}
	s -= down_move;			// 将已爬上的高度減去當天滑下的高度
	i++;					// 天數自增
}
printf("蝸牛需要 %d 天爬到葡萄架頂\n", i);	// 輸出結果      
int n1 = 1, nm = 100;			// 定義查找範圍
int i, j, flag;					// 定義循環控制變量
if (n1 == 1 || n1 == 2)			// 處理素數 2
{
	printf("%4d", 2);			// 輸出素數 2
	n1 = 3;						// 将查找範圍移動到 2 以後
}

for (i = n1; i <= nm; i++)
{
	if (!(i % 2))
	{
		continue;		// 如果目前的數能被 2 整除,則結束該輪循環,該數不是素數
	}

	for (flag = 1, j = 3; flag && j < i / 2; j += 2)	// 從 3 開始周遊至 i x 1/2,每次步進 2
	{
		if (!(i % j))
		{
			flag = 0;		// 若能整除,則不是素數
		}
	}
	
	if (flag)
	{
		printf("%4d", i);	// 如果是素數,則輸出該數
	}
}      

繼續閱讀