C語(yǔ)言中函數(shù)指針
函數(shù)調(diào)用的方法有兩種分別如下:
void Fun(void)
{
//do something
}
int main(void)
{
...
Fun();
...
return 0;
}
void Fun(void)
{
//do something
}
int main(void)
{
...
void (*p)(void);
p=Fun;
p();
return 0;
}
上面兩種方式都可以調(diào)用函數(shù),第二種方式在回調(diào)函數(shù)中用的最多,尤其是在操作系統(tǒng)的任務(wù)切換中。 那么我們就重點(diǎn)來(lái)分析下第二種方式。
第二種方式申明了一個(gè)函數(shù)指針p,那為啥寫(xiě)成void(p)(void)? 為啥不直接寫(xiě)成p,不是說(shuō)了函數(shù)名就是該函數(shù)的入口地址,為啥不直接把該地址傳給指針呢,這樣既好理解又方便省事,其實(shí)這樣想不無(wú)道理,但是在C語(yǔ)言中有變量類(lèi)型這個(gè)東東,比如int賦值給char,編譯器就會(huì)報(bào)錯(cuò),同樣的道理函數(shù)也有類(lèi)型,那么既然函數(shù)有類(lèi)型,我們?nèi)绾沃雷兞款?lèi)型呢。 現(xiàn)在寫(xiě)一個(gè)程序如下,注意,程序有錯(cuò)誤,這個(gè)錯(cuò)誤是故意寫(xiě)的,目的就是讓編譯器報(bào)錯(cuò),使用編譯器為gcc。
#include "stdio.h"
void Fun(void)
{
printf("hello world");
}
int main(void)
{
void *p;
p=Fun;
return 0;
}
下面是編譯器輸出:
g++.exe -x c++ -c C:\\Users\\Administrator.SC-201903191934\\Desktop\\unknown1.c -o C:\\Users\\Administrator.SC-201903191934\\Desktop\\unknown1.o -Wall -fallowive -Wno-sign-compare -g
C:\\用戶(hù)\\管理員.SC-201903191934\\桌面\\未知1.c:在函數(shù)中 int main()':** **C:\\Users\\Administrator.SC-201903191934\\Desktop\\unknown1.c:12: warning: invalid conversion from 空 ( )()' 改為 '無(wú)效 '
編譯器報(bào)錯(cuò)意思是不能講void ( )()類(lèi)型轉(zhuǎn)化為void 類(lèi)型。 這個(gè)警告就說(shuō)明了函數(shù)Fun的類(lèi)型是( )()類(lèi)型,而申明的指針類(lèi)型是 ,兩個(gè)類(lèi)型不一致,故導(dǎo)致其錯(cuò)誤,既然這樣,那么如何申請(qǐng)一個(gè)指針類(lèi)型為( )()的呢? C語(yǔ)言中給了函數(shù)指針這個(gè)類(lèi)型,即( )()類(lèi)型,因此為了讓指針指向一個(gè)函數(shù)地址,只需要聲明一個(gè)(*)()類(lèi)型即可。
如下:
#include "stdio.h"
void Fun(void)
{
printf("hello world");
}
int main(void)
{
void (*p)(void); //函數(shù)指針
p=Fun; return 0;
}
這樣就將函數(shù)Fun的地址給指針p了,與其說(shuō)p是一個(gè)函數(shù)指針,倒不如說(shuō)p是一個(gè)函數(shù)名,只是沒(méi)有什么其函數(shù)內(nèi)部,這里可以從舊式的函數(shù)申明上可以看出。
因此要運(yùn)行這個(gè)所謂的函數(shù)p,只需要和函數(shù)使用一樣就行,p();
現(xiàn)在再來(lái)看一個(gè)代碼:
void *Fun(void)
{
printf("hello world");
return NULL;
}
這里函數(shù)Fun改為了有返回值的函數(shù),其返回值為指針void *類(lèi)型,那么我們?nèi)绾蝸?lái)聲明一個(gè)指針指該函數(shù)呢?
從上門(mén)面分析可以看出,該函數(shù)的類(lèi)型應(yīng)該是*(*)(); 所以現(xiàn)在我們需要聲明一個(gè)相同類(lèi)型的指針,即void *(*p)(void); 這樣就只需要p=Fun; 就可以達(dá)到目的了。
#include "stdio.h"
void *Fun(void)
{
printf("hello world");
return NULL;
}
int main(void)
{
void *(*p)(void);
p=Fun;
return 0;
}
**總結(jié):
函數(shù)名也是有類(lèi)型的,因此在C語(yǔ)言中,必須嚴(yán)格遵守類(lèi)型匹配原則。
函數(shù)名的類(lèi)型為(*)()類(lèi)型,如果有返回值,則在最前面增加返回類(lèi)型即可,例如
int * Fun(int,int ); 其函數(shù)類(lèi)型為 ()(int,int),對(duì)應(yīng)的函數(shù)指針為int **(*p)(int,int);
-
C語(yǔ)言
+關(guān)注
關(guān)注
183文章
7644瀏覽量
145611 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4417瀏覽量
67524 -
指針
+關(guān)注
關(guān)注
1文章
484瀏覽量
71854 -
編譯器
+關(guān)注
關(guān)注
1文章
1672瀏覽量
51626 -
回調(diào)函數(shù)
+關(guān)注
關(guān)注
0文章
95瀏覽量
12202
發(fā)布評(píng)論請(qǐng)先 登錄
C語(yǔ)言中void指針的基本認(rèn)識(shí)及典型應(yīng)用
C語(yǔ)言中指針函數(shù)和函數(shù)指針的概念及應(yīng)用示例
C語(yǔ)言中多級(jí)指針的概念和使用方法
c語(yǔ)言指針詳解
C語(yǔ)言指針函數(shù)和函數(shù)指針詳細(xì)介紹
c語(yǔ)言函數(shù)指針定義,指針函數(shù)和函數(shù)指針的區(qū)別
C語(yǔ)言中的野指針是怎么來(lái)的?
C語(yǔ)言中什么是指針數(shù)組
簡(jiǎn)述C語(yǔ)言中指針重點(diǎn)
c語(yǔ)言指針用法詳解:如何使用指針變量做函數(shù)參數(shù)
C語(yǔ)言中函數(shù)指針詳解
評(píng)論