国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

C/C++語言中指向函數的指針

2019-11-17 05:27:03
字體:
來源:轉載
供稿:網友

  “在C語言中,函數本身不是變量,但可以定義指向函數的指針,這種指針可以被賦值、存放于數組之中,傳遞給函數及作為函數的返回值等” --《The C PRogramming Language Second Edition》

下面給出幾個簡單的例子來說明指向函數的指針。

第一個例子說明指向函數的指針如何說明、賦值、調用。

#include
#define TESTDATE 100

int func(int a)  /* func用于打印一個整數 */
{
return printf("%d/n",a);
}


main()
{
int (*FunctionPionter)(int a);
FunctionPionter = func;
(*FunctionPionter)(TESTDATE);
return 0;
}

其中重點語句的含義如下:
int (*FunctionPionter)(int a);
FunctionPionter: 指向一個返回整數的函數的指針,這個指針有一個整數參數。
FunctionPionter = func;
將FunctionPionter指向函數func;其中函數必須已經定義,且函數和函數指針的說明的返回值必須一致。 
(*FunctionPionter)(TESTDATE);
通過函數指針調用函數;因為函數指針已經指向函數,所以用*取出函數指針的內容就為函數本身。

下面這個例子顯示如何將指向函數的指針傳遞給函數、作為函數的返回類型。在這個例子中,有三個函數:
hello:返回字符指針的函數,用來返回字符串“hello world!/n”
RetFunc:返回一個指向函數的指針的函數,且返回指針所指的那個函數為一個返回字符指針的函數。
call:返回一個void *型的指針,且call有一個指向函數的指針的參數,且這個函數指針返回一個字符指針

#include
#define MAX 100

main()
{
void *call(char *(*)());
char *(*RtnFunc())();  

/* 上面兩個說明有些復雜 */

printf("%s",call(RtnFunc()));
return 0;
}

char *hello()
{
return "Hello World!/n";
}

char *(*RtnFunc())()
{
return hello;
}

void *call(char *(*func)())
{
return (*func)();
}

上面的例子中,main()無法直接調用hello函數,利用兩個函數分別返回hello和調用hello,實現了在main()中調用hello。雖然,似乎這個程序顯得多余但卻很好的說明了如何把指向函數的指針傳遞給函數、作為函數的返回。其中call函數利用了void *型指針的靈活機制,使得call的適用性大為增加,這也正是指向函數的指針的優點之一。同樣的例子是《The C Programming Language Second Edition》中下面這個函數調用:

qsort((void **) lineptr, 0, nlines-1, (int (*)(void *, void *))(numeric ? numcmp : strcmp));

其中,使用了兩次強制類型轉換,其中第二甚至是利用指向函數的指針,將函數的類型進行了轉換。當然上面語句在某些編譯器上無法通過,因為某些編譯器要求條件表達:
表達式1 ? 表達式2 : 表達式3
中表達式2與表達式3的類型相同。當然這樣的要求是不符合ANSI標準的。在ANSI標準中,假如表達式2與表達式3的類型不同,則結果的類型由類型轉換規則決定。當然,我們可以變同一下,先將兩個函數的類型進行強制轉換來達到目的:

qsort((void **) lineptr, 0, nlines-1, numeric ? (int (*)(void *, void *))numcmp : (int (*)(void *, void *))strcmp));

對于如何直接說明一個像RtnFunc一樣返回指向函數的指針的函數,我查閱了不少資料,都沒有找到答案,最后是自己硬著頭皮摸索出來的。由此,我也對C的復雜說明有了更深刻的體會,將在以后的技術日記中寫出來。當然在我看來,過多的、不合適的使用這些復雜說明,并不是一種好的編程風格,因為它將使程序變得難以理解,同時也增加了出錯的可能性。
一個比較好的折衷的方法是使用typedef來使程序的含義明朗。下面給出用typedef給寫上面那個程序的例子,其中定義個一個類型PtoFun,用typedef說明PtoFun是指向函數的指針類型,指針所指的函數返回一個字符指針,且沒有參數。

#include
#define MAX 100


typedef char *(*PtoFun)();

main()
{
void *call(PtoFun);
PtoFun RtnFunc();

printf("%s",call(RtnFunc()));
return 0;
}

char *hello()
{
return "Hello World!/n";

}

PtoFun RtnFunc()
{
return hello;
}

void *call(PtoFun func)
{
return (*func)();
}

改寫后的程序的可讀性大為增加,給人一目了然的感覺。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 洪雅县| 岗巴县| 冕宁县| 浪卡子县| 秦安县| 潮州市| 葫芦岛市| 九寨沟县| 琼结县| 板桥市| 苏州市| 永定县| 福清市| 东阳市| 凤阳县| 林甸县| 桐乡市| 叙永县| 弥渡县| 佛冈县| 济南市| 同江市| 老河口市| 梅河口市| 中宁县| 罗城| 德州市| 乌拉特后旗| 云南省| 平定县| 泰安市| 曲靖市| 南溪县| 齐河县| 黄山市| 旬阳县| 安徽省| 铜梁县| 浦江县| 松潘县| 婺源县|