当前位置: 首页 > news >正文

深⼊理解指针(7)

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;
//}

相关文章:

  • 第九节:文件操作
  • Pytorch深度学习框架60天进阶学习计划 - 第55天: 3D视觉基础(二)
  • 精华贴分享|【零敲碎打12】类筹码数据构建-散户行为倾向
  • flutter 专题 五十六 Google 2020开发者大会Flutter专题
  • javaScript——DOM(四)
  • DataWorks Copilot 集成 Qwen3-235B-A22B混合推理模型,AI 效能再升级!
  • TCP和UDP的数据传输+区别
  • Linux 部署以paddle Serving 的方式部署 PaddleOCR CPU版本
  • Decode
  • OpenAI 2025 4月最新动态综述
  • 【Unity】如何解决UI中的Button无法绑定带参数方法的问题
  • 《机器学习中的过拟合与模型复杂性:理解与应对策略》
  • 关于 MCP 的理论知识学习
  • HAproxy+keepalived+tomcat部署高可用负载均衡实践
  • buildroot 和 busybox 系统的优缺点
  • vue2中如何自定义指令
  • 最新DeepSeek-Prover-V2-671B模型 简介、下载、体验、微调、数据集:专为数学定理自动证明设计的超大垂直领域语言模型(在线体验地址)
  • C++继承(下)
  • 监听滚动事件
  • Ubuntu平台使用aarch64-Linux交叉编译opencv库并移植RK3588S边缘端
  • 美商界报告:全美超86万岗位依赖对华出口,关税将重创美国出口商
  • 美航母撞船后又遇战机坠海,专家:长时间作战部署疲于奔命是主因
  • 原国家有色金属工业局副局长黄春萼逝世,享年86岁
  • 韩国下届大选执政党初选4进2结果揭晓,金文洙、韩东勋胜出
  • TAE联手加州大学开发出新型核聚变装置:功率提升百倍,成本减半
  • 王星昊再胜连笑,夺得中国围棋天元赛冠军