發信人: ax.bbs@bbs.ee.nthu.edu.tw. (athena), 信區: test
標  題: 星星流講座 0010
發信站: ☆清華電機☆ (Mon May  8 00:17:10 1995)
轉信站: star

星星流講座 0010         C 語言教室

第 3 講 之 3            基本的輸出和輸入
                        Topic: Concept of Functions

前面我們常常用到 printf 這個函數,然而卻沒有對它作詳細的說明,
這裡我們就來對它做一個初步的介紹。

在介紹之前,我們先來談談 C 語言裡一個非常非常重要的觀念:函數。

什麼是函數呢?簡單的來說,函數就像一部機器,你輸入一些資料,函
數就會根據這些資料製造出對應的結果,並把結果資料傳回給你:

                輸入  ┌────┐  輸出
              ───→│ 函  數 │────→
                      └────┘
 

一個函數,不一定要有輸入,但是一定要有輸出。由於函數的這種
特性,我們也把函數稱做副程式 (subprogram, subroutine),意思是程
式之中的小程式,負責完成某一種特定的工作。

函數在 C 語言中,以類似下例的型態出現:

                int getchar (void)
               ↗      ↑       ↖
        回傳值型態   函數名稱   函數參數 (parameters, arguments)

函數名稱的命名規則和變數名稱相同 (事實上,函數可以視為變數的一
種衍生型態,容後再述)。函數的型態就是函數傳回來的值的資料型態
值得注意的是,回傳值型態只能是基本的資料型態 (如 char、int ....
等等),而不可以是衍生的資料型態 (如前面提過的陣列)。

函數名稱後面緊接著小括號,小括號內括的叫函數的參數,也可稱為是函
數的引數。函數的引數就是你給函數的輸入資料,如果這個函數
不需要輸入資料,我們就給它一個叫做 void 的參數,void 是無、沒有的
意思。同樣地,如果函數沒有回傳值,那麼它的回傳值型態也是 void。
前面提過,一個函數必須要有輸出,但是輸出並不等於傳回值,請務必弄
清楚你的觀念。(一個比較簡單的想法:函數可以輸出結果到螢幕上,不必
傳回任何值)

如果函數需要很多個參數,那麼函數參數之間必須用逗號 , 來分開,例如:

                void show_result (int a, float b, char c[])
                                     ↗
                                 用逗號隔開
 

上面的例子中示範了如何傳入陣列做參數,不過這是比較暴力的方法,正
統的作法以後會提到。每一個函數都包含了兩個部份:宣告 (declaration)
和函數本體 (function body),每個函數在使用之前都必須經過宣告
什麼是宣告呢?就是定義函數的回傳值、函數名稱和函數的參數型態,例
如:

/* dummy.c */
#include <stdio.h>

void a (int b);         /* declaration */

void main (void)
{
    a (2);              /* call of function */
}

void a (int b)
{
    printf ("%d\n", b);
}
 

執行結果

2

我們看到 main 函數中使用了 a 這個函數,所以在 main 函數的函數本
體之前必須對 a 這個函數加以宣告。在比較嚴格 (或說是比較老式) 的
C 語言編譯器中,所有的函數宣告都必須放在程式的最前面,通常是
緊接於編譯指示之後。這種函數的提前宣告也被稱為函數原型 (function
prototype),函數原型必須和函數本體前的宣告一致,也就是說,你
若是事先宣告了

void a (int b);

那麼當你在寫函數本體的時候,函數的回傳值就一定得是 void,參數就
只能有一個有號整數。不過參數的名字就不一定非 b 不可了,你可以寫


void a (int c)
{
    printf ("%d\n", c);
}

只要參數的型態和個數正確就可以,名字並不重要。但通常我們為了避免
出錯,還是盡量地使前後一致為佳。