函数指针

在Linux 内核中经常看见,数组指针,指针数组,函数指针等,这些都是C语言的高级语法,之前我们了解了数组指针和指针数组,在学习他们的过程中使用逐层分析的方法,这回我们使用这个方法再来学习函数指针。

1.函数指针是什么?
1.1.概念理解
(1)函数指针、数组指针、普通指针之间并没有本质区别,区别在于指针指向的东西是个什么玩意。
(2)函数的实质是一段代码,这一段代码在内存中是连续分布的(一个函数的大括号括起来的所有语句将来编译出来生成的可执行程序是连续的),所以对于函数来说很关键的就是函数中的第一句代码的地址,这个地址就是所谓的函数地址,在C语言中用函数名这个符号来表示。
(3)结合函数 的实质,函数指针其实就是一个普通变量,这个普通变量的类型是函数指针变量类型,它的值就是某个函数的地址(也就是它的函数名这个符号在编译器中对应的值)
1.2.先回顾什么是数值指针
数组指针就是一个指向数组的指针,定义方式为int (*p)[5];
我们当时怎们分析的?
第一步:核心是p
第二步:逐层结合,p先和*结合是指针,p再和[]结合是数组,也就是一个指向数组的指针。

好,来看下面的代码

int (*p)(int , int );

采用分析数组指针的方法
第一步:核心是p
第二步:逐层结合,p先和* 结合是指针,p再和后面的( )结合是函数,(比如函数 func( ),名字后面和( )结合肯定是函数。)
第三步:既然是函数,参数和返回值是什么样的?p后面的()里有两个int的参数,p前面有一个int,说明,函数返回值是int类型。

1.2.深入理解int ( * p)(int ,int );
所有的指针本质都一样,指向int数据的就是int* 指针,指向数组的就是int( * p)[ ],指向函数的就是void ( * p)(void)类型。所有的指针都包含三部分,定义,赋值,解引用。来看函数指针的这三步。

int a(int b,char c);           //声明一个函数
main()
{
    int (*pa)(int b,char c)   //定义函数指针
    pa=a;                       //给函数指针赋值  等价于p=&a;
    pa(int b,char c);           //解引用函数指针
}

上面的函数指针的类型是 int( * )( int ,int );函数名本身就是该函数第一句代码的首地址了,所以可以直接把函数名赋值给函数指针,在这里需要注意的是,在数组int b[10]里面,b和&b分别做右值时含义和类型都不一样,而对于函数int a();
a和&a做右值的含义和类型是一模一样的。

2.函数指针实战
写一个复杂的函数指针的实例:
比如函数是strcpy函数 char * strcpy(char * dest, const char * src);

分析:
第一步:找函数的返回值分类型:char*
第二步:找参数列表:char * dest,const char*src
第三步:定义出函数指针。对应的函数指针是:char * ( * pstrcpy)(char * dest, const char * src);

总结:
函数: int a(int qqq,char www); 的函数指针就是 int ( * pa)(int qqq,char www) 定义指向a函数的指针
pa=a; // 给该指针赋值,让该指针指向一个合法的函数。
pa(int qqq,char www) //调用

最后来看下面的代码,思考输出的结果。

#include<stdio.h>

void a(void);
void b(void);
void main()
{
    void (*p)(void);    //函数指针声明
    p = b;              //赋值
    p();                //通过函数指针调用函数
}                                                                   
void a(void)
{
    printf("this is in func a!");
}
void b(void)
{
    printf("this is in func b!");
}

输出结果是什么?

原文地址:https://www.cnblogs.com/1024E/p/13209620.html