在 C 語(yǔ)言中的每個(gè)函數(shù)都有自己特定的類(lèi)型,函數(shù)的類(lèi)型由返回值,參數(shù)類(lèi)型和參數(shù)個(gè)數(shù)共同決定。如 int add(int i, int j) 的類(lèi)型為 int(int, int);在 C 語(yǔ)言中通過(guò) typedef 為函數(shù)類(lèi)型重命名,如 typedef type name(parameter list);例:typedef int f(int, int);typedef void p(int);
創(chuàng)新互聯(lián)建站是專(zhuān)業(yè)的寧晉網(wǎng)站建設(shè)公司,寧晉接單;提供成都網(wǎng)站建設(shè)、網(wǎng)站制作,網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專(zhuān)業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行寧晉網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專(zhuān)業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專(zhuān)業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!
我們來(lái)講下函數(shù)指針,那么什么是函數(shù)指針呢?函數(shù)指針用于指向一個(gè)函數(shù),函數(shù)名是執(zhí)行函數(shù)體的入口地址。可通過(guò)函數(shù)類(lèi)型定義函數(shù)指針:FuncType* pointer;也可以直接定義:type(*pointer)(parameter list);其中 pointer 為函數(shù)指針變量名,type 為所指函數(shù)的返回值類(lèi)型,parameter list 為所指函數(shù)的參數(shù)類(lèi)型列表。
那么我們?cè)谇度胧降墓P試面試中經(jīng)常遇到:如何使用 C 語(yǔ)言直接跳轉(zhuǎn)到某個(gè)固定的地址處開(kāi)始執(zhí)行?這個(gè)問(wèn)題咋一看感覺(jué)無(wú)解啊,但其實(shí)我們仔細(xì)想想,還是有辦法的。就是通過(guò)函數(shù)指針來(lái)實(shí)現(xiàn)的,我們?cè)谇懊嬷v過(guò)函數(shù)名是執(zhí)行函數(shù)的入口地址,那么我們是否可以通過(guò)函數(shù)指針來(lái)指向這個(gè)地址呢?當(dāng)然可以啦,這就實(shí)現(xiàn)了直接跳轉(zhuǎn)到一個(gè)固定的地址處開(kāi)始執(zhí)行。
下來(lái)我們以代碼為例進(jìn)行分析,代碼如下
#include <stdio.h>
typedef int(FUNC)(int);
int test(int i)
{
return i * i;
}
void f()
{
printf("Call f()...\n");
}
int main()
{
FUNC* pt = test;
void(*pf)() = &f;
printf("pf = %p\n", pf);
printf("f = %p\n", f);
printf("&f = %p\n", &f);
pf();
(*pf)();
printf("Function pointer call: %d\n", pt(2));
return 0;
}我們來(lái)分析下這個(gè)代碼,我們?cè)诘?行定義了 FUNC 為 int(int) 型的。所以我們?cè)诘?7行用它這種類(lèi)型的指針來(lái)指向函數(shù) test 是不會(huì)出錯(cuò)的,第18行定義的指針 pf 也是如此。接下來(lái)我們打印三個(gè)地址值,理論上三個(gè)值應(yīng)該一樣,因?yàn)樗麄兌际窃诖蛴『瘮?shù) f 的入口地址。接著第24行的 pf() 相當(dāng)于調(diào)用了 f(),第26行也相當(dāng)于調(diào)用了 f()。最后打印了 pt(2) 相當(dāng)于 test(2) ,會(huì)打印出 4。我們來(lái)看看編譯結(jié)果

接下來(lái)我們來(lái)講下回調(diào)函數(shù)。那么什么是回調(diào)函數(shù)呢?它是利用函數(shù)指針實(shí)現(xiàn)的一種調(diào)用機(jī)制。回調(diào)函數(shù)原理是:a> 調(diào)用者不知道具體事件發(fā)生時(shí)才需要調(diào)用具體函數(shù);b> 被調(diào)函數(shù)不知道何時(shí)被調(diào)用,只知道需要完成的任務(wù);c> 當(dāng)具體事件發(fā)生時(shí),調(diào)用者通過(guò)函數(shù)指針調(diào)用具體函數(shù)。回調(diào)機(jī)制中的調(diào)用者和被調(diào)函數(shù)互不依賴(lài)。
下來(lái)我們以代碼為例進(jìn)行分析,代碼如下
#include <stdio.h>
typedef int(*Weapon)(int);
void fight(Weapon wp, int arg)
{
int result = 0;
printf("Fight boss!\n");
result = wp(arg);
prinf("Boss loss: %d\n", result);
}
int knife(int n)
{
int ret = 0;
int i = 0;
for(i=0; i<n; i++)
{
printf("Knife attack: %d\n", 1);
ret++;
}
return ret;
}
int sword(int n)
{
int ret = 0;
int i = 0;
for(i=0; i<n; i++)
{
printf("Sword attack: %d\n", 5);
ret += 5;
}
return ret;
}
int gun(int n)
{
int ret = 0;
int i = 0;
for(i=0; i<n; i++)
{
printf("Gun attack: %d\n", 10);
ret += 10;
}
return ret;
}
int main()
{
fight(knife, 3);
fight(sword, 4);
fight(gun, 5);
return 0;
}我們這份代碼是利用了游戲中打老怪的思想,我們打老怪時(shí)不知道用的是什么武器。所以只能通過(guò)函數(shù)指針來(lái)調(diào)用具體的函數(shù),也就是所謂的武器。然后我們定義了小刀、劍和槍三種武器,在主函數(shù)中打老怪的時(shí)候分別調(diào)用了三種武器。我們來(lái)看看編譯結(jié)果

我們發(fā)現(xiàn)用小刀的***力最低,用槍的***力最高。通過(guò)這個(gè)示例代碼,我們很好地詮釋了回調(diào)函數(shù)的原理。通過(guò)本節(jié)對(duì)函數(shù)指針的學(xué)習(xí),總結(jié)如下:1、C 語(yǔ)言中的函數(shù)都有特定的類(lèi)型;2、可以使用函數(shù)類(lèi)型定義函數(shù)指針;3、函數(shù)指針是實(shí)現(xiàn)回調(diào)機(jī)制的關(guān)鍵技術(shù),通過(guò)函數(shù)指針可以在 C 程序中實(shí)現(xiàn)固定地址跳轉(zhuǎn)。
歡迎大家一起來(lái)學(xué)習(xí) C 語(yǔ)言,可以加我QQ:243343083。
網(wǎng)頁(yè)標(biāo)題:C之函數(shù)與指針(三十二)
網(wǎng)頁(yè)鏈接:http://www.chinadenli.net/article30/gegdso.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、品牌網(wǎng)站設(shè)計(jì)、軟件開(kāi)發(fā)、網(wǎng)站導(dǎo)航、網(wǎng)站收錄、品牌網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)