C语言中函数指针详解

描述

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);

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分