好,再下來我們要開始介紹函式。
那函式呢,是組成程式的基本元件,也就是說一個程式裡頭你可以有很多
個函式,那在我們之前呢,我們都只寫了一個函式。那個函式 就是
main 就是 m,a,i,n。所以我們之前呢程式裡頭就是一個函式。
那從現在開始呢,我們這個程式裡頭可能會有很多函式,所以這邊要開始介紹。
那函式可以主要分為兩大類,第一種
叫系統定義的函式,第二種叫使用者定義的函式。我們首先一開始會 開始來介紹這種系統定義函式,那舉個例子來講,比如說像
printf,我們之前一直在用,一直在用 printf 去把資料做輸出,但是我們從來也沒有去探討說
printf 到底怎麼把東西印出來的。所以這些東西,我們知道有,知道
怎麼用就可以了。所以系統會幫我們定義很多這種東西,這樣我們就不用自己 再重新寫。那我們先開始介紹系統定義的這一個函式。
那我們這邊舉一個例子,比如說我們寫一個 sys-function.c,這裡頭呢
一開始我們宣告兩個變式叫 i,j,然後兩個那個被整數
被整浮點數 x,y,然後我們把 i 丟進來,然後我們開始
呼叫一個函式,這個函式呢叫 ABS,簡單來說就是取絕對值的意思。
那這個 i 就是它的參數,所以我們把 i 讀進來取絕對值,把它放到 j 裡頭,然後把它印出來,就是這麼簡單。
那如果想運用這種系統定義的函式的話,你必須跟系統講說,跟你這程式有一個
跟系統講說我要用這個東西,那怎麼跟系統講呢?那你就把它標註上,把它放進來。比如說我- 們之前用
scanf 事實上呢,我們都說要把這個東西包含進來,stdio.h
就是這個 系統的標頭檔,那這邊的話各位可以看到我開始用一個叫做註協的東西,註協就是長這個樣子。
這是 /* 開始 / 結束。
* 作結尾,*/ 作結尾。那中間就可以寫說
你想讓使用者看到的資訊,比如說這裡我就說, 我把這個標頭檔抓進來,
事實上是為了 printf 跟 scanf,這樣子寫就清楚了。
那事實上呢,比如說像 ABS 這種東西,ABS 這種東西事實上是在 standard library 裡頭定義的。
那我們就要想辦法去把 standard library 把它定義進來。那另外一個比如說像
math.h,那這個就要用 sin,我們用 sin 的時候就要把 math.h
點進來。這就是之後我會,在這裡會說明。比如說我們現在把 這個 x
讀進來,然後對它取 sin 就是那個正弦函數,然後把它值送到
y 裡頭,然後再把 y 印出來。所以我們這裡用了哪些東西呢?我們用了 printf,scanf,abs
跟 sin, 那這些呢都要把對應的這個標頭檔,把它放到前面弄進來。也許各位會說,
可是我不知道說我想用這個東西到底標頭檔長什麼樣子,這時候我們就需要去在網路上去查找- 一些資料。
那在這邊的話,可以在這裡找到,比如說像我們計算機程式概論,計算機程式設計這門課裡頭- 有些參考資料,
那我邊有一個 www.cplusplus.com 這一個網頁,
大家可以上去看,那事實上這種類似的網頁很多,你可以在網絡上那個都可以找得到。
這搜尋能搜尋得到,那這個裡頭比如說我搜尋 abs,
它就告訴我說啊,如果是 C
的界面的話,它大概長這個樣子,它會給一些示範用法,那其中我們就要注意就是說 它告訴你說是在
standard library 才能找到這個 abs,那我們現在看看剛剛那個
sin, 好,sin 在那個,這裡頭的話你就可以找到說,是在
standard 是在 math.h 裡頭可以找得到,所以這些都是可以找得到的。那找得到的話我們就知道要
到時候要去包含哪一個標頭檔。那這樣就很容易了,你想用什麼函式,你就 引入它適當的標頭檔,這樣就可以了。所以我們輸入
-100 的話,跟 1.23 的話就得到這樣的答案。中間的這個 abs -100 的 abs 絕對值是 100,那
1.23 按照進度去求正弦函數,大概得到 0.94 左右。
所以這個標頭檔是很重要的,你使用系統定義的函式,你必須引用想呼叫的函式對應的標頭檔。
那標頭檔的詳細的函式的呼叫的方法,那這樣的話編譯器就能夠幫我們檢查,你的呼叫方法是- 否正確。
那我們來看一下這些標頭檔,剛剛已經介紹過要去哪裡
include。那什麼叫做 正確的使用呢?因為一個函式它有一些固定的使用方法的,那
這些東西呢包括了函式的名稱,比如說正弦函數就叫 sin 它不能叫 cos。
好,參數,正弦函數有幾個參數呢?就一個參數,所以你放兩項也不對。
那這些參數的型別又是什麼呢?那也要講清楚,那回傳值這些
合稱函式的原型。所以函式的原型包括它的名稱,例如說你要怎麼樣去調用它,參數
你要怎麼樣去放那些參數,跟它那些參數的形態,還有回傳值,那回傳值的形態又是什麼?
那函式的原型就好像是函式的使用說明書,我詳細記載了函式應該
要怎麼樣使用。就是這些東西,那知道了這些,這些東西以後呢,所以你要讓系統知道說,
原來正弦函數呢,它是引用一個參數, 引用那個回傳一個值。那這些就放在標頭檔裡頭,所以
我們這個編譯器,看到這些標頭檔之後呢,它就能正確判斷是否要那個,怎樣來
檢查說你用的這個用法是不是正確。比如說我們 abs 寫成這樣,abs(int
n), 好,意思就是說,abs 的這個函數的名稱叫 abs 啊,就這 abs。
那名稱的類別呢,必須跟這個變數相同,好,所以你怎麼命名函數呢,事實上是跟
變數是一模一樣的,那這個函數只有一個參數,那類別是 int 啊,int。
那參數呢,用小括號括起來,放在函數名稱的後面,如果有多個的話就用逗號把它隔開。
那函數有一個回傳值,這前面就是回傳值,它的類別是 int,所以你必須在函式前面跟它講說你的回傳值是什麼?
那直接在原型後面加上分號表示結束,意思就是說函式原型
只會說明這個函式要怎麼用,那內部的實作呢,就另外再說。
那我們知道那件事情,我們知道 abs 要怎麼呼叫以後,我們就可以看說
編譯器如果看到這一行,它會怎麼辦?它會檢查說,之前有一個,已經有人跟我講過有一個 函式叫
abs 了,所以沒有問題啊,有 abs,那後面幾個參數呢,有一個,它的形態對不對呢,正確的
是 i。所以當編譯器知道這個資訊,
這個資訊是在標頭檔裡頭,它就可以來檢查說這個到底正不正確。
好,它的用法正不正確,所以它可以確認說函式的名稱,參數,回傳值都沒有問題了。名稱- 確實沒有
問題。參數確實沒有問題,參數的類別也沒有問題,回傳值也沒有問題,它就說哦,這個是正- 確的用法,是可以接受的。
那我們再來看 sin 這個東西,那 sin
的話正弦函數,所以它有一個引數, 一個參數是型別為
double,那回傳值也是一個 double。所以 函數的名稱是
sin,那這沒有問題,這個參數沒有問題。回傳值只有一個 回傳值,它的回傳值
assign 到一個,指定到一個 double 數值,沒有問題。
所以編譯器看了這個以後,它從那個,它從這些
標頭檔裡面看到這個東西以後,它就可以來判別說你寫的方法正不正確。如果你亂寫一通,
它當然就會說,跟我剛剛看到的函式的那個,那個型別不一樣,它就會告訴你說你用錯了。
所以我們正確的呼叫的方法就是說,我們要,名稱要正確啊。
類別要正確,回傳值呢要處理。
比如說,我們在這個 ideone 裡頭,我們剛才已經把它打開了,所以我們現在可以來
編譯一下,如果說我不小心寫錯了,abs 呢,給它兩個參數,你叫它去編譯,叫它編譯。
最後它說
看不懂了,這裡為什麼會這樣子呢?太多引數了,這樣不對的 這樣不對的,那如果說你告訴它,你這個
sin 呢 有另外一個引數,甚至有三個引數,
存起來,那你把它丟進去,一跑, 它就說
不太對勁,為什麼你的 sin 有 x,y,x 三個引數呢?
這樣,這樣,這樣不正確,跟我之前在 math.h 裡頭看到的
這個,的那個原來那個原型不一致了,所以它就有辦法檢查出來了。
[空白_錄音] [空白_錄音]
[空白_錄音] [空白_錄音]