C語言中函數指針
函數調用的方法有兩種分別如下:
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;
}
上面兩種方式都可以調用函數,第二種方式在回調函數中用的最多,尤其是在操作系統的任務切換中。 那么我們就重點來分析下第二種方式。
第二種方式申明了一個函數指針p,那為啥寫成void(p)(void)? 為啥不直接寫成p,不是說了函數名就是該函數的入口地址,為啥不直接把該地址傳給指針呢,這樣既好理解又方便省事,其實這樣想不無道理,但是在C語言中有變量類型這個東東,比如int賦值給char,編譯器就會報錯,同樣的道理函數也有類型,那么既然函數有類型,我們如何知道變量類型呢。 現在寫一個程序如下,注意,程序有錯誤,這個錯誤是故意寫的,目的就是讓編譯器報錯,使用編譯器為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:\\用戶\\管理員.SC-201903191934\\桌面\\未知1.c:在函數中 int main()':** **C:\\Users\\Administrator.SC-201903191934\\Desktop\\unknown1.c:12: warning: invalid conversion from
空 ( )()' 改為 '無效 '
編譯器報錯意思是不能講void ( )()類型轉化為void 類型。 這個警告就說明了函數Fun的類型是( )()類型,而申明的指針類型是 ,兩個類型不一致,故導致其錯誤,既然這樣,那么如何申請一個指針類型為( )()的呢? C語言中給了函數指針這個類型,即( )()類型,因此為了讓指針指向一個函數地址,只需要聲明一個(*)()類型即可。
如下:
#include "stdio.h"
void Fun(void)
{
printf("hello world");
}
int main(void)
{
void (*p)(void); //函數指針
p=Fun; return 0;
}
這樣就將函數Fun的地址給指針p了,與其說p是一個函數指針,倒不如說p是一個函數名,只是沒有什么其函數內部,這里可以從舊式的函數申明上可以看出。
因此要運行這個所謂的函數p,只需要和函數使用一樣就行,p();
現在再來看一個代碼:
void *Fun(void)
{
printf("hello world");
return NULL;
}
這里函數Fun改為了有返回值的函數,其返回值為指針void *類型,那么我們如何來聲明一個指針指該函數呢?
從上門面分析可以看出,該函數的類型應該是*(*)(); 所以現在我們需要聲明一個相同類型的指針,即void *(*p)(void); 這樣就只需要p=Fun; 就可以達到目的了。
#include "stdio.h"
void *Fun(void)
{
printf("hello world");
return NULL;
}
int main(void)
{
void *(*p)(void);
p=Fun;
return 0;
}
**總結:
函數名也是有類型的,因此在C語言中,必須嚴格遵守類型匹配原則。
函數名的類型為(*)()類型,如果有返回值,則在最前面增加返回類型即可,例如
int * Fun(int,int ); 其函數類型為 ()(int,int),對應的函數指針為int **(*p)(int,int);
-
C語言
+關注
關注
180文章
7614瀏覽量
137398 -
函數
+關注
關注
3文章
4344瀏覽量
62864 -
指針
+關注
關注
1文章
481瀏覽量
70593 -
編譯器
+關注
關注
1文章
1642瀏覽量
49229 -
回調函數
+關注
關注
0文章
87瀏覽量
11606
發布評論請先 登錄
相關推薦
評論