ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## **1.类型转换** 所谓通用类型指针,其实就是void \*;该指针可以用来转换不同类型参数指针变量,如下例子(main\_3.c),我们定义一个用于输出任意类型变量内容的函数,函数要求传入参数时指定该参数的类型(比如uint16\_t,string等)来指示输出: ![](https://img.kancloud.cn/cf/d0/cfd0258fcf36bff5171ee1a0f688de0e_832x480.png =600x) ### 函数将void \*类型格式化为想要类型的指针,然后取值输出,调用方式: ![](https://img.kancloud.cn/7d/3d/7d3deb7dbbdf2759b68273f63c216fc6_618x500.png =600x) ### 编译输出: ![](https://img.kancloud.cn/15/9e/159e6209a7389eec4b0c2e0081d5705a_832x298.png =600x) ## **2.代理传参调用** 下面这个例子会比较抽象(涉及到指针和地址比较抽象的转换关系,了解即可,不要求能理解里面的转换逻辑),源码放在main\_4.c中,需要很好理解地址和指针变量的关系,我们借助void \*的列表来存储一段空间,并用来做回调函数的调用,从而达到代理调用的过程。 ### 思考一下:int \*pa = (int *)malloc(sizeof(int)); 这个代码中,指针变量本身的地址在哪,指针变量指向的地址在哪,指针变量指向的地址里面的内容是什么,先清这几个概念再继续往下看,首先指针变量本身的地址是&pa;指针指向的地址是pa(准确来说是(uint64\_t)pa);指针指向的地址里面的内容是*pa。 ### 声明几个函数如下: ![](https://img.kancloud.cn/cd/91/cd91188cbf6900be4207177dfcf9b5dd_832x94.png =600x) ### 然后有一定测试代码如下: ![](https://img.kancloud.cn/90/75/9075a7b21a049ce3a66e57cca6b59623_832x648.png =600x) ### 首先我们申请了2个参数(args),然后给两个参数进行赋值,第一个值是一个函数的地址,第二个值是一个uint16\_t类型的数值(12345);然后调用tester进行测试,函数tester里面把args的内容(函数和数值)取出来,进行调用,也就是把第一值强制转换成函数指针(第21行),然后传入数值完成调用。 再看args这几个声明的函数实现: ![](https://img.kancloud.cn/e3/a7/e3a7adcf19de6c97c0049a86aebbc251_832x684.png =600x) ### 在函数args\_add\_func里面,首先我们把指针变量func所指向的地址保存了起来(loader),然后loader被放在args中,由于index是0,因此是放在第一个位置;在函数args\_add\_uint16里面,我们则是把变量value的数值保存起来(pvalue),然后放在args第二个位置(index是1)。再回过头看tester里面的代码大概就能看懂了。 ### 编译运行,结果等价于直接调用show函数:show(12345): ![](https://img.kancloud.cn/93/a7/93a7def518e8e0126cd4e678d61713ef_832x200.png =600x)