C語言小白入門之「C語言 " 函數 "」

虎牙來了 發佈 2020-01-11T13:46:46+00:00

如果是基本數據類型作為函數的形參,那是簡單的值傳遞,將實參a的值賦值給了形參b,相當於 inta =10;intb = a; b =9; a和b是分別有著不同內存地址的2個變量,因此改變了形參b的值,並不會影響實參a的值。

一、函數的分類

前面已經說過,C語言中的函數就是面向對象中的"方法",C語言的函數可以大概分為3類:

1.主函數,也就是main函數。每個程序中只能有一個、也必須有一個主函數。無論主函數寫在什麼位置,C程序總是從主函數開始執行

2.開發人員自定義的函數,可有可無,數目不限

3.C語言提供的庫函數,例如stdio.h中的輸出函數printf()和輸入函數scanf()


二、函數的聲明和定義

雖說C中的函數類似於Java中的方法,但在使用上還是有區別的。

1.在Java中,每個方法的定義順序沒有限制,在前面定義的方法內部可以調用後面定義的方法


第1行定義的test方法可以調用在第5行定義的sum方法

2.在標準C語言中,函數的定義順序是有講究的,默認情況下,只有後面定義的函數才可以調用前面定義過的函數


第5行定義的main函數調用了第1行的sum函數,這是合法的。如果調換下sum函數和main函數的順序,在標準的C編譯器環境下是不合法的。

3.如果想把其他函數的定義寫在main函數後面,而且main函數能正常調用這些函數,那就必須在main函數前面作一下函數的聲明


我們在第2行做了sum函數的聲明,然後在第6行(main函數中)就可以正常調用sum函數了。

函數的聲明格式:

返回值類型 函數名 (參數1, 參數2, ...)

可以省略參數名稱,比如上面的sum函數聲明可以寫成這樣:

intsum(int,int);

只要你在main函數前面聲明過一個函數,main函數就知道這個函數的存在,就可以調用這個函數。究竟這個函數是做什麼用,還要看函數的定義。如果只有函數的聲明,而沒有函數的定義,那麼程序將會在連結時出錯。

4.在大型的C程序中,為了分模塊進行開發,一般會將函數的聲明和定義(即實現)分別放在2個文件中,函數聲明放在.h頭文件中,函數定義放在.c源文件中

下面我們將sum函數的聲明和定義分別放在sum.h和sum.c中

sum.h文件

sum.c文件


然後在main.c中包含sum.h即可使用sum函數

其實sum.h和sum.c的文件名不一樣要相同,可以隨便寫,只要文件名是合法的

運行步驟分析:

1> 在編譯之前,預編譯器會將sum.h文件中的內容拷貝到main.c中;

2> 接著編譯main.c和sum.c兩個源文件,生成目標文件main.obj和sum.obj,這2個文件是不能被單獨執行的,原因很簡單:

* sum.obj中不存在main函數,肯定不可以被執行

* main.obj中雖然有main函數,但是它在main函數中調用了一個sum函數,而sum函數的定義卻存在於sum.obj中,因此main.obj依賴於sum.obj

3> 把main.obj、sum.obj連結在一起,生成可執行文件;

4> 運行程序;

說到這裡,有人可能有疑惑:可不可以在main.c中包含sum.c文件,不要sum.h文件了?

大家都知道#include的功能是拷貝內容,因此上面的代碼等效於:

這麼一看,語法上是絕對沒有問題的,但是絕對運行不起來,在連結時會出錯。原因:編譯器會編譯所有的.c源文件,這裡包括main.c、sum.c,編譯成功後生成sum.obj、main.obj文件,當連結這兩個文件時連結器會發現sum.obj和main.obj裡面都有sum函數的定義,於是報"標識符重複"的錯誤。

▓有人可能覺得分出sum.h和sum.c文件的這種做法好傻B,好端端多出2個文件,你把所有的東西都寫到main.c不就可以了麼?

● 沒錯,整個C程序的代碼是可以都寫在main.c中。但是,如果項目做得很大,你可以想像得到,main.c這個文件會有多麼龐大,會嚴重降低開發和調試效率。

● 要想出色地完成一個大項目,需要一個團隊的合作,不是一個人就可以搞的定的。如果把所有的代碼都寫在main.c中,那就導致代碼衝突,因為整個團隊的開發人員都在修改main.c文件,張三修改的代碼很有可能會抹掉李四之前添加的代碼。

● 正常的模式應該是這樣:假設張三負責編寫main函數,李四負責編寫一系列的自定義函數,張三需要用到李四編寫的某個函數,怎麼辦呢?李四可以將所有的函數聲明在一個.h文件中,比如lisi.h,然後張三在他自己的代碼中包含lisi.h文件,接著就可以調用lisi.h中聲明的函數了,而李四呢,可以獨立地在另外一個文件中(比如lisi.c)編寫函數的定義,實現那些在lisi.h中聲明的函數。這樣子,張三和李四就可以相互協作、不會衝突。

三、函數的形參和實參

在定義函數時,函數名後面的()中定義的變量稱為形式參數(形參);在調用函數時傳入的值稱為實際參數(實參)。

如果是基本數據類型作為函數的形參,那是簡單的值傳遞,將實參a的值賦值給了形參b,相當於

inta =10;intb = a;

b =9;

a和b是分別有著不同內存地址的2個變量,因此改變了形參b的值,並不會影響實參a的值。

上述代碼的輸出結果為:

我是一名從事了10年開發在退休邊緣垂死掙扎的高齡程式設計師,最近我花了一些時間整理了一個完整的學習C語言、C++的路線,項目源碼和工具。對於想學習C/C++的小夥伴而言,學習的氛圍和志同道合的夥伴很重要,筆者推薦一個C語言/C++編程愛好者的聚集地>>>私信我【編程學習】即可!

歡迎初學和進階中的小夥伴。希望你也能憑自己的努力,成為下一個優秀的程式設計師。工作需要、感興趣、為了入行、轉行需要學習C/C++的夥伴可以一起學習!

喜歡小編的記得動動您的小指點個關注喲!最後分享一張C/C++編程學習路線圖給愛學習的小夥伴們~


關鍵字: