函式除了可以回傳一般的變數類型外,也可以回傳指標,包含了變數指標、陣列指標、函式指標等等
函式回傳變數指標
函式可以回傳一個變數的位址
1 | int * fun_rt_para(int a) |
以上程式碼顯示結果如下,函式將b的位址傳回,這裡要注意的是b必須是全域變數或是static變數,因為local變數的生命週期只有在此函式內(local變數一般放在stack或CPU register),出了這個函式再透過指標位址取值,有可能取到錯誤的值
函式回傳陣列指標
函式也可以回傳陣列指標
1 | int * fun_rt_arr() |
顯示結果如下,不過使用此方式缺點為caller無法從function name得知陣列大小,caller有可能讀取到邊界外的值,甚至破壞到陣列外的資料,此方法在安全性來講並不妥當
若想讓caller看function就可以知道陣列大小,可以使用以下方式,輸出結果和上面的例子相同,但事實上回傳的type不完全相同
上例回傳的type為int *p
,指向int的指標
下例回傳的type為int (*p)[3]
指向int[3]的指標
1 | int (* fun_rt_arr())[3] |
函式回傳函式指標
函式也可以回傳另一個函式的指標
1 |
|
細部解析函式的宣告,從最內部的fun_rt_fun_ptr開始
int (* fun_rt_fun_ptr(int a))(int b)
- (向右看)fun_rt_fun_ptr為輸入int a的函式
- (向左看)fun_rt_fun_ptr回傳一指標
- (向右看)此指標為函式指標,且為輸入int b的函式
- (向左看)此回傳的函式指標回傳值為int
註:對於較複雜的宣告可參考以下文章 http://www.codeproject.com/Articles/7042/How-to-interpret-complex-C-C-declarations
指標函式回傳函式指標
指標函式回傳函式指標和函式回傳函式指標,原理沒什麼太大的不同,只是宣告上會更為複雜些
1 | int f1(int b) |
函式宣告的部分和函式回傳函式指標沒什麼不同,這也是非常正常的,因為所謂的指標函式並不是指函式本身是指標,而是以指標的方式串接此函式,因此要注意的地方是
int (* (*func_ptr[])(int))(int) = {fun_rt_fun_ptr1, fun_rt_fun_ptr2};
除了宣告的型別必須是回傳函式指標的函式之外,還必須有一個儲存函式指標的陣列
printf("output value : %d\n\n", func_ptr[0](1)(10));
printf("output value : %d\n\n", func_ptr[0](2)(20));
printf("output value : %d\n\n", func_ptr[1](10)(30));
printf("output value : %d\n\n", func_ptr[1](20)(40));
以上的行為依序如下
- call fun_rt_fun_ptr1帶入參數1,因參數為1進入f1帶入參數10,回傳值為11
- call fun_rt_fun_ptr1帶入參數2,因參數為2進入f2帶入參數20,回傳值為22
- call fun_rt_fun_ptr2帶入參數10,因參數為10進入f3帶入參數30,回傳值為31
- call fun_rt_fun_ptr2帶入參數20,因參數為20進入f4帶入參數40,回傳值為42