函數指針在C/C++中很常用,最近遇到了一非常有趣的問題,函數指針的參數和函數的形參個數不匹配時會遇到的問題,下面看代碼。
// // main.cpp // FuncPointer // // Created by ChengChao on 14-9-21. // Copyright (c) 2014年 cc. All rights reserved. // #includeusing namespace std; int add(int a, int b) { return a + b; } int main(int argc, const char * argv[]) { //單參函數指針 typedef int(*fun)(int); fun f = (fun)add; int ret = f(20); cout << "ret=" << ret << endl; //3參函數指針 typedef int(*fun2)(int, int, int); fun2 f2 = (fun2)add; int ret2 = f2(20, 30, 10); cout << "ret2=" << ret2 << endl; return 0; }
根據輸出可以看到 add函數實際有兩個參數,但是我們通過函數指針調用時,分別傳入了1個參數和3個參數,這兩種用法均沒用報編譯錯誤。
1.當我們只傳入1個參數時, 通過函數指針調用函數時,函數所在的臨時棧空間分別為形參a和b創建了兩個int類型的變量,但實際我們只傳了1個實參給add函數的形參a賦值了20,形參b並沒有進行賦值初始化,所以形參b是一個隨機生成的垃圾數值,就出現了ret是一個很大的隨機輸出結果。
2.當我們傳入了3個參數時,通過函數指針調用函數時,編譯器檢測到傳入的3個參數中的前兩個就可以滿足臨時棧中的形參a和b正常的初始化,在add函數所在的棧空間中,只有兩個int類型的變量空間, 第三個參數根本就沒有空間來保存它,所以會被編譯器過濾掉,就相當於只傳了2個參數分別給形參a和b賦值初始化,所以ret2輸出結果是正常的。