6.4 帶參數的函數

C語言學習欄目目錄

目錄

章節程序演示


 

現在,相信大家已經熟悉了帶參數的函數。要掌握函數,還要學習如何編寫自己的函數程序清單中有一個pound()函數,打印指定數量的#號(該符號也叫作編號符號或井號)。該程序還演示了類型轉換的應用。


/************************************************************************
功能:定義一個帶一個參數的函數
************************************************************************/

#include <stdio.h>
void pound(int n);		// ANSI函數原型聲明
int main(void)
{
	int times = 5;
	char ch = '!';		// ASCII碼是33
	float f = 6.0f;
	pound(times);		// int類型的參數
	pound(ch);			// 和pound((int)ch);相同
	pound(f);			// 和pound((int)f);相同
	system("pause");	// 暫停控制檯
	return	0;
}
void pound(int n)		// ANSI風格函數頭
{						// 表明該函數接受一個int類型的參數
	while (n-- > 0)
		printf("#");
	printf("\n");
}

運行該程序後,輸出如下:

#####
#################################
######
請按任意鍵繼續. . .

如果函數不接受任何參數,函數頭的圓括號中應該寫上關鍵字  void。由於該函數接受一個 int 類型的參數,所以圓括號中包含一個int類型變量n的聲明。參數名應遵循C語言的命名規則。

聲明參數就創建了被稱爲形式參數(formal  argument或formalparameter,簡稱形參)的變量。該例中,形式參數是 int 類型的變量 n。像pound(10)這樣的函數調用會把 10 賦給 n。在該程序中,調用pound(times)就是把 times 的值(5)賦給 n。我們稱函數調用傳遞的值爲實際參數(actualargument或actual  parameter),簡稱實參。所以,函數調用pound(10)把實際參數10傳遞給函數,然後該函數把10賦給形式參數(變量n)。也就是說,main()中的變量times的值被拷貝給pound()中的新變量n。

注意 實參和形參

在英文中,argument和parameter經常可以互換使用,但是C99標準規定了:對於actual argument或actual parameter使用術語argument(譯爲實參);對於formal argument或formal parameter使用術語parameter(譯爲形參)。爲遵循這一規定,我們可以說形參是變量,實參是函數調用提供的值,實參被賦給相應的形參。因此,在上程序清單中,times是pound()的實參,n是
pound()的形參。類似地,在函數調用pound(times + 4)中,表達式times + 4的值是該函數的實參。

變量名是函數私有的,即在函數中定義的函數名不會和別處的相同名稱發生衝突。如果在pound()中用times代替n,那麼這個times與main()中的times不同。也就是說,程序中出現了兩個同名的變量,但是程序可以區分它們。

現在,我們來學習函數調用。第1  個函數調用是pound(times),times的值5被賦給n。因此, printf()函數打印了5個井號和1個換行符。第2個函數調用是pound(ch)。這裏,ch是char類型,被初始化爲!字符,在ASCII中ch的數值是33。但是pound()函數的參數類型是int,與char不匹配。程序開頭的函數原型在這裏發揮了作用。原型(prototype)即是函數的聲明,描述了函數的
返回值和參數。pound()函數的原型說明了兩點:

該函數沒有返回值(函數名前面有void關鍵字);

該函數有一個int類型的參數。

該例中,函數原型告訴編譯器pound()需要一個int類型的參數。相應地,當編譯器執行到pound(ch)表達式時,會把參數ch自動轉換成int類型。在我們的系統中,該參數從1字節的33變成4字節的33,所以現在33的類型滿足函數的要求。與此類似,最後一次調用是pound(f),使得float類型的變量被轉換成合適的類型。

在ANSI C之前,C使用的是函數聲明,而不是函數原型。函數聲明只指明瞭函數名和返回類型,沒有指明參數類型。爲了向下兼容,C現在仍然允許這樣的形式:

void pound(); /* ANSI C之前的函數聲明 */

 如果用這條函數聲明代替pound.c程序中的函數原型會怎樣?第 1 次函數調用,pound(times)沒問題,因爲times是int類型。第2次函數調用,pound(ch)也沒問題,因爲即使缺少函數原型,C也會把char和short類型自動升級爲int類型。第3次函數調用,pound(f)會失敗,因爲缺少函數原型,float會被自動升級爲 double,這沒什麼用。雖然程序仍然能運行,但是輸出的內容不正確。在函數調用中顯式使用強制類型轉換,可以修復這個問題:

pound ((int)f); // 把f強制類型轉換爲正確的類型

注意,如果f的值太大,超過了int類型表示的範圍,這樣做也不行。

章節程序演示

程序清單演示了本章介紹的幾個概念,這個程序對某些人很有用。程序看起來很長,但是所有的計算都在程序的後面幾行中。我們儘量使用大量的註釋,讓程序看上去清晰明瞭。請通讀該程序,稍後我們會分析幾處要點。

(若程序再VS中無法運行Scanf函數,請參考:VS2015使用scanf報錯解決方案


/************************************************************************
功能:演示本章介紹的幾個概念
************************************************************************/

#include <stdio.h>
const int S_PER_M = 60;					// 1分鐘的秒數
const int S_PER_H = 3600;				// 1小時的分鐘數
const double M_PER_K = 0.62137;			// 1公里的英里數
int main(void)
{
	double distk, distm;				// 跑過的距離(分別以公里和英里爲單位)
	double rate;						// 平均速度(以英里/小時爲單位)
	int min, sec;						// 跑步用時(以分鐘和秒爲單位)
	int time;							// 跑步用時(以秒爲單位)
	double mtime;						// 跑1英里需要的時間,以秒爲單位
	int mmin, msec;						// 跑1英里需要的時間,以分鐘和秒爲單位
	printf("這個程序是對你比賽時間公制轉換\n");
	printf("一英里的跑步時間和你的平均成績\n");
	printf("速度(英里/小時).\n");
	printf("請輸入以公里爲單位的長跑\n");
	scanf("%lf", &distk);				// %lf表示讀取一個double類型的值
	printf("下一步以分鐘和秒爲單位輸入時間\n");
	printf("從輸入分鐘開始\n");
	scanf("%d", &min);
	printf("輸入你的秒數 .\n");
	scanf("%d", &sec);
	time = S_PER_M * min + sec;			// 把時間轉換成秒
	distm = M_PER_K * distk;			// 把公里轉換成英里
	rate = distm / time * S_PER_H;		// 英里/秒×秒/小時 = 英里/小時
	mtime = (double)time / distm;		// 時間/距離 = 跑1英里所用的時間
	mmin = (int)mtime / S_PER_M;		// 求出分鐘數
	msec = (int)mtime % S_PER_M;		// 求出剩餘的秒數
	printf("你跑 %1.2f km (%1.2f 英里) 用 %d min, %dsec.\n",distk, distm, min, sec);
	printf("這個速度相當於跑了一英里 %d min, ",mmin);
	printf("%d sec.\n你的平均速度是 %1.2f mph.\n", msec,rate);
	system("pause");					//暫停控制檯
	return 0;
}

程序清單把時間轉換成分鐘和秒,除此之外還使用了類型轉換。爲什麼要進行類型轉換?因爲程序在秒轉換成分鐘的部分需要型參數,但是在公里轉換成英里的部分需要浮點運算。我們使用強制類型轉換運算符進行了顯式轉換。實際上,我們曾經利用自動類型轉換編寫這個程序,即使用int類型的mtime來強制時間計算轉換成整數形式。但是,在測試的11個系統中,這個版本的程序在1個系統上無法運行,這是由於編譯器(版本比較老)沒有遵循C規則。而使用強制類型轉換就沒有問題。對大家而言,強制類型轉換強調了轉換類型的意圖,對編譯器而言也是如此。

下面是程序清單的輸出示例:

這個程序是對你比賽時間公制轉換
一英里的跑步時間和你的平均成績
速度(英里/小時).
請輸入以公里爲單位的長跑
10
下一步以分鐘和秒爲單位輸入時間
從輸入分鐘開始
36
輸入你的秒數 .
23
你跑 10.00 km (6.21 英里) 用 36 min, 23sec.
這個速度相當於跑了一英里 5 min, 51 sec.
你的平均速度是 10.25 mph.
請按任意鍵繼續. . .

源碼 

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