1.函数指针变量的创建
在x86环境下:
我们发现:以函数是有地址的,函数名就是函数的地址,当然也可以通过& 函数名 的⽅式获得函数的地址。
如果我们要将函数的地址存放起来,就得创建函数指针变量咯,函数指针变量的写法其实和数组指针⾮常类似。如下:
函数指针类型解析:
再加上一组:
发现pf的前面可以不带*
2.两段有趣的代码
(*(void (*)())0)();
//解释一下
// void (*)()—— 是函数指针类型
//(void (*)()) —— 括弧里面放类型就是强制转换
//(void (*)())0 —— 将0强制转换为 void (*)() 的函数指针类型
//这就意味着我们假设 0 地址处放着无参,返回类型是 void 的函数
//最终是调用 0 地址处放的这个函数
void (* signal( int, void(*)(int) ) )(int);
// signal —— 函数名
// int —— 参数1
// void(*)(int) —— 参数2
// signal( int, void(*)(int) ) —— 其中少函数值的返回类型
// 而剩下的void ( )(int); —— 这就是返回类型
// 所以这段代码本质是一个函数声明
// 想表达的意思是:
// void (*)(int)signal( int, void(*)(int) )
// 注意像上一行这样写是会报错的
// 只是想要表达这个意思而已
3.typedef关键字
typedef 是⽤来类型重命名的,可以将复杂的类型,简单化。⽐如,你觉得unsigned int 写起来不⽅便,如果能写成 uint 就⽅便多了,那么我们可以使⽤:
如果是指针类型,能否重命名呢?其实也是可以的,⽐如,将int* 重命名为 ptr_t ,这样写:
但是对于数组指针和函数指针稍微有点区别:
⽐如我们有数组指针类型 int(*)[5] ,需要重命名为 parr_t ,那可以这样写:
注意:
// 新的类型名必须在 * 的右边
函数指针类型的重命名也是⼀样的,⽐如,将 void(*)(int) 类型重命名为 pf_t ,就可以这样写:
那么要简化上述的代码2,可以这样写:
typedef void(*pfun_t)(int);
pfun_t signal(int, pfun_t);
本篇文章中所用到的代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
//int Add(int x, int y)
//{
// return x + y;
//}
//int main()
//{
// printf("%p\n", Add);
// printf("%p\n", &Add);
// return 0;
//}//int Add(int x, int y)
//{
// return x + y;
//}
//
//int main()
//{
// //回忆一下数组指针
// //int arr[10] = { 0 };
// //int (*pa)[10] = &arr;
// //函数与数组类似
// int (* pf)(int, int) = &Add;
// //(int, int) 是因为(int x, int y)
// // int (* pf)是因为int Add
// //pf是专门用来存放函数地址的,pf 就是函数指针变量
// return 0;
//}//int Add(int x, int y)
//{
// return x + y;
//}
//
//int main()
//{
// int(*pf)(int, int) = Add;
//
// int c = Add(2, 3);
// //函数名调用
// printf("%d\n", c);
//
// int d = (*pf)(3, 4);
// //函数指针变量调用
// printf("%d\n", d);
//
// int e = (pf)(4, 5);
// //函数指针变量调用
// printf("%d\n", e);
//
// return 0;
//}看看有趣的代码
//int main()
//{
// (*(void (*)())0)();
// //解释一下
// // void (*)()—— 是函数指针类型
// //(void (*)()) —— 括弧里面放类型就是强制转换
// //(void (*)())0 —— 将0强制转换为 void (*)() 的函数指针类型
// //这就意味着我们假设 0 地址处放着无参,返回类型是 void 的函数
// //最终是调用 0 地址处放的这个函数
// return 0;
//}//void (* signal( int, void(*)(int) ) )(int);signal —— 函数名int —— 参数1void(*)(int) —— 参数2signal( int, void(*)(int) ) —— 其中少函数值的返回类型而剩下的void ( )(int); —— 这就是返回类型所以这段代码本质是一个函数声明想表达的意思是:void (*)(int)signal( int, void(*)(int) )注意像上一行这样写是会报错的只是想要表达这个意思而已
//
//int main()
//{
//
// return 0;
//}