• 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:UsersAdministrator.SC-201903191934Desktopunknown1.c -o C:UsersAdministrator.SC-201903191934Desktopunknown1.o -Wall -fpermissive -Wno-sign-compare -g
    C:UsersAdministrator.SC-201903191934Desktopunknown1.c: In function `int main()':
    C:UsersAdministrator.SC-201903191934Desktopunknown1.c:12: warning: invalid conversion from `void (*)()' to `void*'

    编译器报错意思是不能讲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;
    }

    总结:1. 函数名也是有类型的,因此在C语言中,必须严格遵守类型匹配原则。

               2. 函数名的类型为(*)()类型,如果有返回值,则在最前面增加返回类型即可,例如

                   int * *Fun(int,int );其函数类型为**(*)(int,int),对应的函数指针为int **(*p)(int,int);

  • 相关阅读:
    干货分享|安全测试起航之旅
    干货|宏巍软件之Java线程监控之旅
    大数据时代,业务运维驱动下的企业变革
    什么是业务运维,企业如何实现互联网+业务与IT的融合
    不谈业务运维的IT主管早晚被淘汰 这里是10条干货
    详解APM数据采样与端到端
    CTO对话:云端融合下的移动技术创新
    【1111元天天拿!充一送二玩真哒!】双十一任性活动
    引领手机流量营销 嘿嘿流量打造多场景专业服务
    “烧钱补贴”下的O2O该何去何从?
  • 原文地址:https://www.cnblogs.com/listenscience/p/10991250.html
Copyright © 2020-2023  润新知