[4] 函數

上一節:《入門問題》

實現一個函數的語法如下所示:

類型 函數名(參數列表){ (若干行語句)}

參數列表包含若干個變數類型+變數名,也可以沒有參數:

(參數列表) => (變數類型1 變數名1, 變數類型2 變數名2, ...)

在函數內部的語句中,return語句表示返回函數值,這個值會被返回給調用函數的語句。


所有的運算符本質上都是函數,比如我們可以用函數表示加法

int z(int x, int y){ return x + y;}int main(){ int a = 12; int b = 13; int c = z(a, b); return c;}

顯然,答案是25。

有人會問,不用加號用函數,而且z函數的裡面還是要用加號,這樣的程序有什麼意義呢?

其實還是有意義的:

  • 幫助理解所有運算符本質上就是函數
  • 我們可以構建出極其複雜的函數,但最終的零件還是加減乘除等等基礎的運算(因為CPU在電路層面支持這些運算)

來看下面的v函數,可以使整數被翻轉,比如v(1234)的答案會是4321:

int v(int n){ int m = 0; while (n) { m = m * 10 + n % 10; n = n / 10; } return m;}int main(){ int a = 23456; a = v(a); return a;}

這個程序的運行結果是65432,說明:

  • 雖然你很可能看不懂v函數,但這並不影響你使用它來解決問題。

注意a = v(a)這句話看起來很像是不對的,23456和65432怎麼能相等呢?但其實C語言的等號是賦值的意思,a = v(a)本質上等價於a = 65432,然後a變數的值就變成了65432了。所以,要用動態的眼光來理解程序。

注意v函數中出現的while語法要學完後面的章節才能理解,此小節的重點是如何使用函數解決問題。


我們再來解決一個問題:怎麼刪掉整數的最後一位,例如把1234變成123?這裡用一個t函數來解決:

int trim_tail(int n){ return n / 10;}int main(){ int a = trim_tail(23456); return a;}

運行一下發現,結果是2345,說明:

  • 例子中的函數名叫trim_tail,其實也可以改成其他任意的字母加下劃線組合(只要不是int, return這樣的保留字就行),只不過單詞trim是修剪的意思,而tail是尾巴的意思,用英語單詞或片語給函數起名字可以使程序更易理解(前提是你得懂英語)。
  • n / 10字面意思就是對n除以10的結果取整,但通過函數的名字,閱讀程序的人可以輕鬆地理解程序作者的意圖。有一個非常著名的觀點:程序是寫給人看的,只不過恰好能在計算機上運行起來
  • 函數名或者變數名可以用下劃線_把單詞隔開,目的也是方便人的閱讀。

把v函數和trim_tail函數放到一起會有什麼奇妙的應用呢?來思考一個問題,如何對一個整數「掐頭去尾」,比如把12345變成234?方法如下:

int v(int n){ int m = 0; while (n) { m = m * 10 + n % 10; n = n / 10; } return m;}int t(int n){ return n / 10;}int main(){ int a = 123456; a = t(a); a = v(a); a = t(a); a = v(a); return a;}

t函數跟上面的trim_tail函數內容完全一樣,只是改了一下名字,不會影響程序運行結果。

運行一下,結果果然是2345。在這個程序中,v函數和t函數變成了main函數的零件、工具、助手。

變數的聲明

在上一個程序的main函數中,第一行必須是int a = 123456;也可以像下面這樣拆解:

......int main(){ int a; a = 123456; a = t(a); ......}

但是,你不能把int a;刪掉,只留下a = 123456;。因為C語言的特點是「簡單」,離CPU提供的原始功能很接近。C語言的變數必須事先聲明是整數、浮點數還是什麼類型,這是為了直接在計算機內存上面申請空間。如果變數聲明char a;,程序會只申請一個位元組來存放一個小整數;如果變數聲明double a;,程序會申請8個位元組來存放一個雙精度浮點數。而int a = 123456;只不過是把聲明語句int a;賦值語句a = 123456;合併起來了。

在同一個作用域下,一個變數只能被聲明一次。在函數中聲明的變數,如果沒有賦值,那麼變數的值是難以預測的(但也不是隨機的)。

int類型的變數一般佔用4個位元組的存儲空間。

什麼是位元組

位元組(byte,讀音:拜特)是CPU讀寫內存的最小單位,一個位元組包含8個比特(bit),也就是8個0或1。所以一個位元組能保存的最大整數,就是二進位的11111111,也就是十進位的255。

CPU不能單獨讀寫內存中的某個0或某個1,而是一次性讀寫一個位元組里的所有比特。

計算機世界的單位轉換:1024個Byte=1K,1024K=1M,1024M=1G,1024G=1T (提示:1024是2的10次冪)


所以總結一下函數的作用:

  • C語言的程序就是由若干個函數組成的,main函數是運行整個程序的入口
  • 別人寫的函數可以成為自己程序的零件
  • 把代碼封裝進函數,可以使自己寫的程序更容易被人讀懂。

重要練習

對已經學過的程序代碼進行修改,例如修改變數和函數的名稱,修改程序中包含的數字,還可以修改任意你覺得可以修改的地方(例如新增或刪除分號、回車換行、空格等),然後運行你修改之後的程序,看看程序能否運行。

  • 如果程序不能運行,看下編輯器給你顯示的錯誤提示是什麼意思(可藉助英漢詞典或百度翻譯)
  • 如果程序可以運行,看下運行結果和自己期望的是否一致

這個練習非常重要!因為沒有好奇心主動性的人是不可能學好計算機編程的。


下一講會介紹怎麼把多個文件中的函數合併在一起。

下一節:《多文件工程》


推薦閱讀:

[1] 搭建編程的環境
Teach Yourself Programming in Ten Years - 用十年的時間自學編程

TAG:編程入門 | 編程學習 |