#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 (* signal( int, void(*)(int) ) )(int);
typedef unsigned int unit;
//意思是将unsigned int重命名为unit
typedef 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));//error
printf("%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;
}
简单的理解就是,数组是一个内部存储了同种类型元素的集合,整形数组里面存整形,指针数组里面存指针,函数指针数组里面存函数指针,也就是函数的地址,可以是函数的名称,也可以是存函数地址的指针变量,不过目前看来像是直接用函数名更方便,下标和顺序同样是数组的下标,估计地址也是顺序存储在内存之中,猜的啊猜的,不过似乎也用不到函数地址的地址。
原文:https://blog.51cto.com/15078858/2612758