C語言學習篇 32 為什麼C語言不能函式過載

2021-10-24 17:48:43 字數 2045 閱讀 6508

在日常的開發中,我們有時會遇到根據不同情景,想通過傳入不同型別的引數,而呼叫統一的函式介面,即函式過載。 在c++中原生支援了函式過載, 而在c語言中並不支援,只能通過一些技巧來變相解決, 如定義flag形參, 根據flag值不同,進行不同的處理。例如:

void test(void *a, void *b, int flag)

else if(flag == 2)

else if(flag == 3)

}

而在c++中,直接函式過載:

//***************函式過載***************====

void test(int *a, int *b)

void test(int *a, char *b)

void test(char *a, double *b)

//***************測試********************==int main(void)

注意: 函式返回值不是函式過載的判斷標準!

大家都知道了在c語言中不能函式過載, 究其原因是否思考過呢?接下來我們以下c和c++**為例子,分別用gcc和 g++編譯, 然後再用objdump工具反彙編看看得到的彙編**有什麼區別。

c語言**:

使用編譯無警告無錯誤, 使用以下命令:

使用vi(vim)開啟反彙編結果c_res檔案:

從上圖可知,在c語言中,函式經過c編譯器編譯後,最終得到的符號表(對應函式位址)只包含函式名,跟函式返回型別, 引數型別都無關係。

接下來,我們在看看c++**:

使用g++(c++編譯器)編譯後,同樣再用objdump工具反彙編:

得到反彙編結果檔案cpp_res,vi開啟:

從上圖我們可以看到,函式和編譯後符號對應關係:

函式一:void test(int *a, int *b) —— _z4testpis_

函式二:char test(char *a, int *b) —— _z4testpcpi

函式三: int test(char *a, double *b) —— _z4testpcpd

分析:因為函式一, 二,三,3個函式返回值型別都不同,而最終得到的符號字首都是「_z4」,因此驗證了函式返回值型別不是函式過載的判斷依據。中間的"test"是函式名,這個容易理解,而剩餘的3個字尾:

pis_ 對應 函式一的引數型別 (int , int) 的首字母i, 這裡因為2個型別一致,編譯處理下

pcpi 對應 函式二的引數型別(char, int)的首字母ci

pcpd 對應 函式三的引數型別(char , double)的首字母cd

因此函式引數型別是函式過載的判斷依據!

根據上面的objdump工具反彙編檢視彙編**中符號,我們知道了在c語言中,c編譯器在函式符號處理時,只以函式名稱為符號,因此無法進行函式過載,同時我們也明白了c++中能夠使用函式過載,只是編譯器進行了處理,最終實際呼叫的還是不同的函式,但統一了介面。

最後再次強調下, 要想學好程式語言,尤其是編譯語言,要站在編譯器的角度思考問題,我們可以通過像objdump等工具來輔助我們反推理解。

c語言學習篇

c語言 編譯 執行c程式 include intmain 1.了解c語言結構 main 主函式,所有c語言程式都要包含主函式,從main 函式開始執行 include 是乙個預處理的命令,用來引入標頭檔案 stdio.h 是乙個標頭檔案 標準輸入輸出標頭檔案 printf 格式化輸出到螢幕。prin...

c語言學習筆記32

乙個函式可以返回乙個整型值 字元值 實型值等,也可以返回指標型的資料,即位址。其概念與以前類似,只是返回的值的型別是指標型別而已 定義返回指標值的函式的一般形式為 型別名 函式名 參數列列 左值的概念,可放在賦值號左邊的都可稱為左值 指標變數以及指標變數的間接引用都可作左值,如 int num1 0...

C語言學習 函式篇

函式需要前置,因為系統會預設主函式先執行。為什麼使用函式 避免重複性操作。提高程式可讀性,方便後期修改和完善。有利於程式的模組化。函式類似於乙個黑盒子,有時候不需要知道裡面你怎麼執行的,知道如何用就好了。函式形參用完之後記憶體空間會被釋放,void表示沒有返回值。函式是c語言的基本單位。什麼是函式 ...