7 FUNCTIONS 7.1 INTRODUCTION Program language developers envisioned that a programmer would write a block of code for the solution to a specific task just owe and then allow the program to call the block of code whenever it was needed. In the C programming language, this facility is the function construct. In the FORTRAN and Pascal programming languages, this facility is called subroutines and procedures, respectively. Ch7--1 Functions is the c programming language share many of the same attributes as functions in the mathematics,namely: (1) Name: All C functions will have a name. (2) Argument List: Most functions in C will pass information form the calling function via an argument list. Occasionally, we encounter functions that have empty (void) argument lists. (3) Return Value : Most C functions return information to the calling function via the return value. A few functions do not return a data type at all (void return type). Functions in C are either library or user-defined functions. Ch7--2 7.2 FUNCTIONS REQUIRED IN A C PROGRAM All C programs must have the function called main() because this is where the program’s execution will begin. The function main() may call other user-defined and library functions. You should view the extra time needed to organize the code as a good long-term investment. Ch7--3 7.3 WRITING USER-DEFINED FUNCTIONS rerurnType FunctionName ( zero or more argument declarations); Void createStack ( int iSize ); Float complexMagnitude ( float fRe,float fIm ); Void matrixPrint( char *,double **,int,int ); Void createStack( int ); Float complexMagnitude( float , float); Ch7--4 函式 函式 (function) 也稱為函數,但它並沒有數學上函 數那麼單純,因此稱呼函式較為適宜,在C語言 中佔很重要的地位。在前面幾章中的程式裡都有 一個 main( ) 函式,而在 main( ) 函式中則叫用C 語言函式庫 (library) 所提供的函式,如從鍵盤輸 入資料的 scanf( )、gets( ) 函式、將資料輸出至螢 幕的 printf( ) 函式等,這些函式分別負責一個特 定的工作,若沒有這些事先設計好的函式程式, 那麼您的程式設計工作將會非常困難,雖然如此, C語言的函式庫所提供的函式仍然十分有限,有 些特殊的工作仍須您自己設計特殊的函式。 Ch7--5 本章告訴您如何設計自己的 函式,包括函式的宣告 (declaration)、函式的定義 (definition)、函式的呼叫 (call)、參數 (parameter)、引 數 (argument)、傳回值 (return value) 等相關的課題。 何謂函式?函式乃是C語言 中為完成特定工作的獨立單 元。函式的架構如右圖所示。 Ch7--6 Ex 7-1 設計一個函式sum( ), 傳入兩個整數參數,傳回其和。 Output : the sum of 2 and 3 is 5 Ch7--7 若“函式定義”寫在 main( ) 函式之前,則因 為在 main( ) 中函式呼叫 sum(2,3) 時己經先將 “函式定義”讀入,C 編譯器己經曉得 sum( ) 函式的傳回值資料型態 為整數型態 int sum( ), 且有兩個整數型態的參 數分別為 a 及 b , sum(int a, int b),所以〞 函式宣告〞就可以省略 了,其架構如右圖所示。 Ch7--8 Ex 7-2 設計一個函式sum( ), 傳入兩個整數參數,傳回其和。 Output : the sum of 2 and 3 is 5 Ch7--9 為什麼要使用函式? 使程式更加模組化 (modularity)。使得程式設 計更加容易、維護更加容易、可讀性較高。 避免重複撰寫程式。只要撰寫一個函式,可以 重複呼叫它,例如您撰寫一個 sum( ) 函式, 然後呼叫它 sum(2,3)、sum(123,456) 兩次,縱 使您呼叫它無數次,但在您的程式中,只有一 份 sum( ) 的函式而己。 每設計一個函式,您都可以馬上測試,對於設 計及管理均可提高效率。 Ch7--10 函式宣告 函式宣告 (fuction declaration) 的格式如下: 傳回值型態 函式名稱 (參數型態); 如 int sum ( int , int ↑ ↑ ↑ ↑ ↑ 傳回值型態 為整數型態 函式名稱 為sum 參數型態 為整數型態 參數間以 逗號分開 ); 參數型態 為整數型態 傳回值型態可為C語言任何合乎語法的資料型態,如字元型態 的 char、整數型態的 int、浮點數型態的 float、等等,若沒有傳 回值型態則以關鍵字 void 表示之。 參數型態可為C語言任何合乎語法的資料型態,如字完型態的 char、整數型態的 int、浮點數型態的 flaot、等等,若沒有參數 型態則以關鍵字 void 表示之。如: void funcA (void); /*funcA( )函式沒有傳回值也沒有參數*/ Ch7--11 函式定義 函式定義 (function definition)的格式如下: 傳回值型態 函式名稱 ( 參數型態 參數名稱 ) { 宣告 敘述 } ... ... 如 傳回值型態 ↓ int 函式名稱 ↓ sum { int c; c = a + b; return(c); } 參數型態 ↓ ( int 參數名稱 ↓ 隔開符號 ↓ a ↓ , 參數型態 ↓ int 參數名稱 b) ←───宣告c變數為整數型態 ←───指定敘述 ←───跳躍敘述 Ch7--12 若沒有參數則以 void 表示。〞參數名稱〞稱為形式參數 (formal parameter),或簡稱為參數 (parameter)。執行時參數的值將被〞 函式呼叫〞時的引數 (argument) 值所取代。如: s=sum( 2, 3); /*sum( )函式呼叫*/ 參數 a 被引數 2 所取代,參數 b 被引數 3 所取代,參數與引數 為一對一互相對應。參數儲存的若為數值稱為傳值 (by value), 參數所儲存的若為位址則稱為傳址 (by address)。 〞函式定義〞的本體 (body) 為大括號內所包含者,有兩種成員 (member) :宣告成員及敘述成員。如: { int c; ←─────宣告 c= a + b; ←─┐ return(c); ←─┴───敘述 } Ch7--13 函式呼叫 函式呼叫 (function call) 的格式如下: 函式名稱 ( 引數 ); 或 變數 = 函數名稱 ( 引數 ); 引數為實際的值,引數間以逗號〞 , 〞隔開。 如: s=sum( 2, 3); /*sum( )函式呼叫*/ 〞變數〞為 s,函式名稱為 sum,引數一為實際值 2, 引數二為實際值 3。引數所儲存的若為數值則稱為值 值呼叫 (called by value),引數所儲存的若為位址 則稱為傳址呼叫 (called by address)。如 sum(2, 3) 為傳值呼叫。 Ch7--14 Ex 7-3 設計一個函式可以列印指定個數 count 的指定字元 ch。如 count=6、ch='#' 則顥示 6 個 # 字元。 Output : AAAAAAAAAAAAAAAAAAAA ###### $$$$$$$$$$$$ Ch7--15 Ex 7-4 設計一個函式 getInt( ) 從鍵盤輸入一個整數並回。 設計一個 findMax( ) 函式傳回。設計主程式使用 getInt( ) 函式從鍵盤輸入兩個整數,使用 findmax( ) 函式輸出較大者。 Ch7--16 Output : keyin an integer:135 ←┘ keyin an integer;246 ←┘ max(135, 246)=246 Ex 7-4 設計一個函式 gerScore( ) 從鍵盤輸入一個含小數的成績 並傳回。設計一個 getGrade( )將三個浮點數成績平均後決定成 績等級' A' 至 'E'並傳回。設計主程式使用 getScore( ) 函式從鍵 盤輸入三個浮點數成績,使用 getGrade( ) 取得等級並輸入。 Ch7--17 Output : keyin a score:78.5 ←┘ keyin a score:66.5 ←┘ keyin a score:95.5 ←┘ score = 78.50 66.50 95.50 [註]三個成績 avg = 80.17 [註]平均 grade = B [註]等級 Ch7--18 Ex 7-5 己知整數 n, 請設計一個遞迴函數計算 n 之階乘 (n!) 。 遞迴 (recursive) 為函式呼叫本身,階乘之計算以 n 乘 n-1 階乘表示 n!=n*(n-1)! 計算 n! 和 (n-1)! 的方法是一樣的,只不過引數 n 和 (n-1) 不同而己,如此重覆至 0! 才停止,即: (n-1)!=(n-1)*(n-2)! ... 3!=3*2! 2!=2*1! 1!=1*0! 0!=1 凡遞迴運算必需有一個停止層次才可以,否則無休無止必 導至記憶體不夠使用而當機,本題 0!=1 即為停止層次, 從 n! 一層一層往下至 0! 停止後,又一層一層往上,至 n! 才結束遞迴呼叫。 Ch7--19 Output : keyin m:10 ←┘ [註]鍵入長整數10至m Factor = 1*2*...*10 = 3628800 [註]10!=10階乘為3628800 Ch7--20