C语言进阶:指针的进阶(4)

编辑: admin 分类: c#语言 发布时间: 2021-12-12 来源:互联网
目录
  • 函数指针
    • 函数指针的定义
    • 函数指针的类型
    • 函数指针的使用
    • Example
  • 总结

    函数指针

    函数指针的定义

    整型指针存放整型的地址;数组指针存放数组的地址;那么类比可得,函数指针存放函数的地址。

    显然,函数指针指向函数,存放函数的地址。搞懂函数指针,先了解函数的地址。

    在这里插入图片描述

    &函数名或函数名代表函数地址,与&数组名和数组名略有不同,&函数名和函数名完全一致。

    函数的地址必然要放到函数指针里,函数指针的类型该如何写呢?(以Add函数为例)

    //整型指针
    int* pa = &a;
    //字符指针 
    char* pc = &ch;
    //数组指针
    int(*pa)[10] = &arr;
    //函数指针 - 存放函数地址
    int(*pf)(int, int) = &Add;
    

    函数指针的类型

    int Add(int x, int y);
    //1.
    int(*pf)(int, int) = &Add;
    //2.
    int *pf(int, int) = &Add;
    

    倘若,去掉括号int* pf(int, int),pf就变成函数名,返回类型是int*。所以指针必须带括号。

    前文已交代,指针,去掉指针名和*就是指针所指向的变量类型。

    • 整型指针,去掉*和指针名,即为整型变量类型int。字符指针,为字符类型char。数组指针,去掉后为数组类型int[10]。
    • 函数指针,去掉*和指针名,即为函数的类型int(int,int)。

    总结

    • 去掉指针名pf,即为指针类型int(*)(int, int)
    • 去掉指针名pf和*,即为指针所指向的函数类型为int(int, int)

    函数指针的使用

    计算机硬件程序经常通过调用地址的方式来调用函数,因此需要使用函数指针调用函数。

    int Add(int x, int y)
    {
    	return x + y;
    }
    int main()
    {
        //1.
        int(*pf)(int, int) = &Add;//函数指针指向Add函数
        //2.
        int(*pf)(int, int) = Add;
    	
        //1.
    	int ret = (*pf)(2, 3);
    	//2.
        int ret = pf(2, 3);
    	
        printf("%d\n", ret);
    	return 0;
    }
    

    前面已经交代,&函数名和函数名都是函数的地址,完全等价。所以两种初始化函数指针的方式都可以。

    既然函数名Add可以直接赋值给函数指针pf,说明二者等价。函数指针名pf不解引用也可以使用,*在此处形同虚设,甚至于不写或写多个都并无大碍,仅为理解。

    既然函数名也是函数地址,所以对其解引用也是可以的。我们甚至可以这样写,但仅限娱乐,没有必要。

    Add(2, 3);//1
    (*Add)(2, 3);//2
    (*&Add)(2, 3);//3
    

    Example

    解释下列代码

    //1.
    (*(void(*)())0)();
    //2.
    void (*signal(int, void(*)(int)))(int);
    

    在这里插入图片描述

    1.void(*)()是函数指针类型,放在( )0中,也就是把0强制转换成地址,该地址处存放一个函数其类型为void(*)(void)

    2.这样(void(*)())0就变成了指针,指向该地址的函数,且对其解引用访问此函数。

    3.(*(void(*)())0)也相当于(*pf),通过函数指针解引用代替函数名,函数名后面带上();,相当于(*pf)();也就是一次不传参的函数调用。

    在这里插入图片描述

    1.signal先和()结合,说明signal为函数名,其后(int, void(*)(int)),为其参数列表。

    2.去掉函数名称和参数列表,剩下的void(*)(int)就是返回类型,所以是一次函数声明。

    void (* signal(int, void(*)(int)) ) (int);
    
    typedef void(* pf_t)(int);//typedef简化代码
    pf_t signal(int, pf_t);
    

    总结

    本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注海外IDC网的更多内容!

    【来源:美国cn2服务器 转载请说明出处】