1. 程式人生 > >C語言入門(十二)函式的定義和呼叫

C語言入門(十二)函式的定義和呼叫

函式的定義和呼叫 


前言:

本節介紹C程式的基本單元--函式。函式中包含了程式的可執行程式碼。每個C程式的入口和出口都位於函式main()之中。main()函式可以呼叫其他函式,這些函式執行完畢後程序的控制又返回到main()函式中,main()函式不能被別的函式所呼叫。通常我們把這些被呼叫的函式稱為下層(lower-level)函式。函式呼叫發生時,立即執行被呼叫的函式,而呼叫者則進入等待狀態,直到被呼叫函式執行完畢。函式可以有引數和返回值。

程式設計師一般把函式當作“黑箱”處理,並不關心它內部的實現細節。當然程式設計師也可以自己開發函式庫。
說明一點,函式這一節很重要,可以說一個程式的優劣集中體現在函式上。如果函式使用的恰當,可以讓程式看起來有條理,容易看懂。如果函式使用的亂七八糟,或者是沒有使用函式,程式就會顯得很亂,不僅讓別人無法檢視,就連自己也容易暈頭轉向。可以這樣說,如果超過100行的程式中沒有使用函式,那麼這個程式一定很羅嗦(有些絕對,但也是事實)。

一、函式的定義

一個函式包括函式頭和語句體兩部分。
函式頭由下列三不分組成:
函式返回值型別
函式名
引數表
一個完整的函式應該是這樣的:
函式返回值型別 函式名(引數表)
{
語句體;
}

函式返回值型別可以是前面說到的某個資料型別、或者是某個資料型別的指標、指向結構的指標、指向陣列的指標。指標概念到以後再介紹。
函式名在程式中必須是唯一的,它也遵循識別符號命名規則。
引數表可以沒有也可以有多個,在函式呼叫的時候,實際引數將被拷貝到這些變數中。語句體包括區域性變數的宣告和可執行程式碼。
我們在前面其實已經接觸過函數了,如abs(),sqrt(),我們並不知道它的內部是什麼,我們只要會使用它即可。
這一節主要講解無引數無返回值的函式呼叫。

二、函式的宣告和呼叫

為了呼叫一個函式,必須事先宣告該函式的返回值型別和引數型別,這和使用變數的道理是一樣的(有一種可以例外,就是函式的定義在呼叫之前,下面再講述)。
看一個簡單的例子:
void a(); /*函式宣告*/
main()
{
a(); /*函式呼叫*/
}
void a(); /*函式宣告*/
main()
{
a(); /*函式呼叫*/
}
在main()的前面聲明瞭一個函式,函式型別是void型,函式名為a,無引數。然後在main()函式裡面呼叫這個函式,該函式的作用很簡單,就是輸入一個整數然後再顯示它。在呼叫函式之前聲明瞭該函式其實它和下面這個程式的功能是一樣的:
main()
{
int num;
scanf(%d,&num);
printf(%d\n,num);
}
可以看出,實際上就是把a()函式裡面的所有內容直接搬到main()函式裡面(注意,這句話不是絕對的。)
我們前面已經說了,當定義在呼叫之前時,可以不宣告函式。所以上面的程式和下面這個也是等價的:
void a()
{
int num;
scanf(%d,&num);
printf(%d\n,num);
}
main()
{
a();
}
因為定義在呼叫之前,所以可以不宣告函式,這是因為編譯器在編譯的時候,已經發現a是一個函式名,是無返回值型別無引數的函數了。
那麼很多人也許就會想,那我們何必還要宣告這一步呢?我們只要把所有的函式的定義都放在前面不就可以了嗎?這種想法是不可取的,一個好的程式設計師總是在程式的開頭宣告所有用到的函式和變數,這是為了以後好檢查。
前面說了,在呼叫之前,必須先宣告函式,所以下面的做法也是正確的(但在這裡我個人並不提倡)。
main()
{
void a();
a();
}
void a()
{
int num;
scanf(%d,&num);
printf(%d\n,num);
}
一般來說,比較好的程式書寫順序是,先宣告函式,然後寫主函式,然後再寫那些自定義的函式。
既然main()函式可以呼叫別的函式,那麼我們自己定義的函式能不能再呼叫其他函式呢?答案是可以的。看下面的例子:
void a();
void b();
main()
{
a();
}
void a()
{
b();
}
void b()
{
int num;
scanf(%d,&num);
printf(%d\n,num);
}
main()函式先呼叫a()函式,而a()函式又呼叫b()函式。在C語言裡,對呼叫函式的層數沒有嚴格的限制,我們可以往下呼叫100層、1000層,但是在這裡我們並不提倡呼叫的層數太多(除非是遞迴),因為層數太多,對以後的檢查有一些干擾,函式調過來調過去,容易讓自己都暈頭轉向。
某些人可能就不明白了,看上面的例子,好象使用函式後,程式變的更長了,更不讓人理解。當然,我舉的這個例子的確沒有必要用函式來實現,但是對於某些實際問題,如果不使用函式,會讓程式變的很亂,這涉及到引數問題,我們下一節再說。