C/C++编程笔记:C语言精华解析之void *指针,指针中的万能指针

C/C++编程笔记:C语言精华解析之void *指针,指针中的万能指针

什么是万能指针?

万能指针其实就是void *类型的指针,而void *指针一般被称为通用指针或叫泛指针。它是C语言关于纯粹地址的一种约定。当某个指针是void型指针时,所指向的对象不属于任何类型。 因为void指针不属于任何类型,不可以对其进行算术运算,比如自增,编译器不知道其自增需要增加多少。

C/C++编程笔记:C语言精华解析之void *指针,指针中的万能指针

而对于char *型指针,自增一定是指针指向的地址加1,int*型指针自增,则偏移4。这个在指针的运算中p+n的解释中已经很详细的介绍过,这里不再累赘,有兴趣的可以自行查阅。

在C/C++中,在任意时刻都可以使用其它类型指针来代替void指针,或者用void指针来代替其他类型指针。 这样就可以衍生出很多比较有用的技巧。指针的本质,是其值为一个地址,那么延伸一下: 当使用关键字void声明指针变量时,它将成为通用指针变量。任何数据类型(char,int,float等)的任何变量的地址都可以赋值给void指针变量。这就是为什么把它称之为万能指针了。

万能指针使用规则

(1)使用前必须被初始化

(2)解引用过程必须强制转换

万能指针能被任何类型指针初始化,万能指针也和其他类型指针一样,可以当做函数参数,函数返回值,以及充当函数指针皆可。

万能指针操作基本数据类型

对指针变量的解引用,使用间接运算符*达到目的。但是在使用空指针的情况下,需要转换指针变量以解引用。这是因为空指针没有与之关联的数据类型。编译器无法知道void指针指向的数据类型。因此,要获取由void指针指向的数据,需要使用在void指针位置内保存的正确类型的数据进行类型转换。

C/C++编程笔记:C语言精华解析之void *指针,指针中的万能指针

万能指针充当函数返回值

万能指针充当函数返回值直接看下库中提供的动态内存申请函数即可,自己想要写的话稍微麻烦些,动态申请内存函数如下:

C/C++编程笔记:C语言精华解析之void *指针,指针中的万能指针

而我们在实用的时候为什么要强制转换就一目了然了。

C/C++编程笔记:C语言精华解析之void *指针,指针中的万能指针

万能指针充当函数参数

当我们想要设计一个可以传入任何类型的指针的函数的时候,我们就可以把参数设计为void *类型,而对于这类函数,内存的重新申请realloc函数其实也是void *的参数,很多操作内存的函数,参数设计其实都是void *类型的指针,如果你对于C语言掌握的可以,我相信下面两个函数你应该都了解过:

C/C++编程笔记:C语言精华解析之void *指针,指针中的万能指针

万能指针充当函数指针调用函数

虽说万能指针充当函数指针调用函数的方式真正自己开发的时候很少用,但是有幸我的学生面试的时候就遇到过这样的一道笔试题,所以在这里就给大家讲解下,如下代码,实现通过万能指针对函数的调用:

C/C++编程笔记:C语言精华解析之void *指针,指针中的万能指针

别人会问题 (*(void(*)())pVoid)()是做什么的? 初看,大家是不是满脑子黑人问号?其实结合上面的代码看,就知道其实就是一个无返回值无参函数通过万能指针调用而已。考究的无非以下C语言知识:

(1)函数指针调用函数: (*函数指针名)(参数表);

(2)强制转换语法:(目标类型)变量

(3)指针的类型: 去掉变量名剩下的就是指针的类型

而对函数print的函数指针是 :void (*p)() ,其实就是用(*p)替换函数名,就是该函数的函数指针,所以去掉变量名剩下的就是指针的类型,即:void (*)() ,然后pVoid 调用函数的方式: (*pVoid)(); 然后把类型拿过来强制转换即可得到:(*(void(*)())pVoid)(),明白了吧!就这么简单。

ps: 在单片机开发中,万能指针往往用来实现数据的非易失存储。所谓非易失存储,就是数据改写后在掉电后仍然能保持。有兴趣的可以自我拓展下哦!

自学C/C++编程难度很大,如果你想更快提升自己的编程能力和编写项目的水平,欢迎一起共同成长!

C语言C++编程学习交流圈子,【点击进入微信公众号:C语言编程学习基地

有一些源码和资料分享,欢迎转行也学习编程的伙伴,和大家一起交流成长会比自己琢磨更快哦!