之前,我们就接触过数组指针,数组指针是用来存放数组的地址,同理,函数指针就是用来存放函数的地址.那么函数指针怎么用呢,看这样一段代码:
#include <stdio.h>
#include <stdlib.h>
void test(char* str)
{
printf("%s\n", str);
}
int main()
{
test("hello");
system("pause");
return 0;
}
分析:test把hello的首地址传给了str,所以打印的就是hello,程序一走,结果就是helo,没问题。那么我们怎样拿到一个函数的地址呢?数组的地址,我们取地址就可以了,那么函数的地址是不是也是直接取地址呢?我们来看一下:如果是地址,我们通过%p的形式打印出来,代码入下:
#include <stdio.h>
#include <stdlib.h>
void test(char* str)
{
printf("%s\n", str);
}
int main()
{
printf("%p\n", &test);
system("pause");
return 0;
}
我们来看看打印结果:
0131114F,果然是一个地址,我们知道,&数组名,取出的是数组的地址,数组名也是个地址,而且是首元素的地址,他们的意义不同,但是值是一样的,那我们能不能只写个函数名,也说它是个地址呢,通过验证,我们发现是可以的,函数的地址通过&函数名拿到,也可以直接通过函数拿到,那么又有一个问题,函数的&函数名取的是函数的地址,函数名单独放是不是表示函数的首元素地址呢?但是我们知道函数哪来的首元素,所以说:函数的地址就不能跟数组的地址类比了,函数的名字取地址和函数名作为地址是一模一样的,都代表函数的地址,没有区别。
函数的地址,我们已经有办法获取,那如果想要把函数的地址存起来,怎么存?这就引入了函数指针。
下面来看两个有趣的代码:
(*(void(*)())0)();
这句代码的意思是:调用0地址处的函数,调用的函数的参数是无参,返回类型 为void (具体分析请详看 《深度理解指针数组, 函数指针数组.......》那篇博客)
void(*signal(int,void(*)int)))(int);
这句代码的意思是: signal是一个函数声明,函数的参数为int和一个函数指针;该函数指针指向的函数参数为int,返回类型为void;signal函数的返回类型也为函数指针,该函数指针指向的参数为int,返回类型为void(具体分析请详看《深度理解指针数组, 函数指针数组.......》那篇博客)