伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

函数指针的认识

来源:本站原创 浏览:48次 时间:2023-06-27
函数指针的认识
#include <Stdio.h>int Add(int a, int b){    return a + b;}//函数指针 - 是指向函数的指针 - 是存放函数地址的指针void Print(char* str){    printf("%s\n",str);}int main(){    int a = 0;    int b = 10;    int sum = Add(a, b);    printf("%p\n", &Add);    printf("%p\n", Add);    //函数名 和 &函数名 都是函数的地址    int (*pa)(int, int) = Add;//函数指针的形式->> //返回值类型 指针名 参数类型;    printf("%p\n", pa);    printf("%d\n", (*pa)(5, 5));    void (*pc)(char*) = Print;    (*pc)("hehehaha");    return 0;}

一个能让人认识函数指针的简单的代码,函数指针也是指针,比如数组指针指向一个数组,函数指针指向一个函数,而类似于数组名是一个数组的地址,二维数组名是一个二维数组首行的地址,函数名也是函数的地址,取地址符加上函数名也是函数的地址,解引用也能调用函数,直接使用地址也能调用函数。

(* ( void( *)( ) )0 )();
 (*   ( void(*)() )0   )();

一个看起来很让人摸不着头脑的语句,慢慢分析一下

  1. void(*)()为一个函数的类型,就像前面的指针变量去掉指针名剩下的就是指针类型,整形变量去掉变量名,剩下的就是整形
  2. 所以void(*)()为一个返回值为空的无参函数的指针的类型
  3. ()在这儿作为强制类型转换符
  4. (void(*)())0的意思就是把0的类型转换为一个返回值为空的无参数指针类型的指针(地址)
  5. *(函数指针)表示将这个指针解引用,寻找一个函数的地址
  6. 所以(函数指针)() -- ( (void(*)() 0 )( ) 意思为通过被强制转换成一个无参返回类型为空的指针类型的 0地址调用一个无参函数
void (* signal( int, void( *)(int) ) )(int);
void (*   signal(  int, void(*)(int) )  )(int);
  1. 同样的,返回值类型 (函数名)(参数类型)
  2. 函数名,signal是一个函数声明,signal(int, void(*)(int)),第一个参数为整形,第二个参数为函数指针,该函数指针指向的参数是int,返回类型为void
  3. 而函数signal(int, void(*)(int))的返回值类型为是一个函数指针,指向的参数为int,返回类型为void
  4. void(*)(int) 类型的函数指针
    这同样是一个很让人费解的语句,通俗的将就是函数用指针来套娃,有一个关键字叫做typydef,有类型重命名的功能,可以利用这个关键字来将这句话进行一定程度的简化
    typedef unsigned int unit;//意思是将unsigned int重命名为unittypedef void(*pfun_t)(int);//typedef关键字 - 将 void(*)(int)类型简化为pfun_t,写作typedef void(*pufn_t)(int)pfun_t signal(int, pfun_t);

    typedef关键字 - 将 void()(int) 类型简化为pfun_t,写作 typedef void(pufn_t)(int),与一般的类型命名不同,变量类型+变量名称。函数指针的命名都在 (*)里面,对于这一点的理解和认识对于书写和函数指针的理解很重要。

    * 在调用的时候的含义
    #include <Stdio.h>int Add(int a, int b){return a + b;}void Print(char* str){printf("%s\n", str);}int main(){int a = 0;int b = 10;int sum = Add(a, b);int (*pa)(int, int) = Add;printf("%d\n", Add(5, 5));printf("%d\n", pa(5, 5));printf("%d\n", (*pa)(5, 5));//printf("%d\n", *pa(5, 5));//errorprintf("%d\n", (**pa)(5, 5));//调用的时候是否有*并不会影响结果,函数名就是地址,通过函数名可以调用到函数,即为通过地址直接调用到函数//当然也可以通过*解引用先找到函数再使用,多余的*是没有意义的void (*pc)(char*) = Print;(pc)("hehehaha");(*pc)("hehehaha");return 0;}

    调用的时候是否有并不会影响结果,函数名就是地址,通过函数名可以调用到函数,即为通过地址直接调用到函数,当然也可以通过解引用先找到函数再使用,多余的*是没有意义的。

函数的指针数组
int Add(int x, int y){    return x + y;}int Sub(int x, int y){    return x - y;}int Mul(int x, int y){    return x * y;}int Div(int x, int y){    return x / y;}#include <stdio.h>int main(){    //需要一个数组,这个数组可以存放四个函数的地址 - 函数指针的数组    int (*pa)(int, int) = Add;//函数指针    int (*parr[4])(int, int) = { Add,Sub,Mul,Div };    int i = 0;    for (i = 0; i < 4; i++)    {        printf("%d  ", (*parr[i])(5, 5));    }    return 0;}

简单的理解就是,数组是一个内部存储了同种类型元素的集合,整形数组里面存整形,指针数组里面存指针,函数指针数组里面存函数指针,也就是函数的地址,可以是函数的名称,也可以是存函数地址的指针变量,不过目前看来像是直接用函数名更方便,下标和顺序同样是数组的下标,估计地址也是顺序存储在内存之中,猜的啊猜的,不过似乎也用不到函数地址的地址。

  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net