C++:指针:void*指针(跳跃力未定的指针)
创始人
2024-02-11 16:03:24

先分享一段代码,觉得很有意思

#include
void* say_hello(void* args){std::cout<< "Hello world"<< std::endl;return 0;
}

上面这段代码,我们看到函数的返回值类型竟然是 void*  ,形参也是 void*  ,按照一般的理解,如果返回值和形参都是 void 的,那么返回值直接写一个 void 的,形参直接不写就可以。为什么要这样多此一举了 ?

1:void* 到底是什么

在C语言中,*类型就是指针类型,比如 int *p  ,double* q 。这个虽然是不一样的指针,但是大小是一样的(sizeof(p) == sizeof(q)),因为他们都是同一种 *类型(或者因为他们保存的是变量的地址,而变量地址大小由于系统结构决定),那int *p  ,double* q到底有什么不同 ? 看下图

  •  很明显,当指针偏移一个位置时候,int *p 和double *q 指向的位置是不一样的。
  • 也就是说:对指针而言,如果我们在前面规定了它的类型,那就是相当于决定了它的“跳越力”。“跳跃力”就比如说上面: int 类型跳越了 4字节, double类型跳越了 8字节。
  • 基于这样的理解,那么 void* 的定义就是 : void *是一个跳跃力未定的指针。

1.1 那么跳跃力什么时候定:

这就是它的神奇之处了,我们可以自己控制在需要的时候将它实现为需要的类型。这样做的好处就是节约代码,实现泛型编程。

2:void* 详解

2.1 :void* 可以指向任何类型的指针,但是带类型的指针不能指向void* 指针

正常来说如果两个指针类型不一样的话,两个指针变量是不可以直接相等 赋值得,例如: int *a , float *b  ,如果令:  a=b 这个是会编译报错的,但是void* 指针可以等于任何类型的指针。

int * a ;

float *f;

a= b;  // 编译会报错的

    void* pv;
    float f = 5.5;
    float* pf = &f;
    pv = pf;    // 这样是没问题

2.2 void* 指针只有进行了强制类型转换才可以正常取值


// void* 类型指针解析#include
using namespace  std;int main() {void* pv;float f = 5.5;float* pf = &f;pv = pf;//cout << *pv << endl;  // 语法错误:表达式必须是指向完整对象类的指针cout << *(float*)pv << endl; //强制类型转换后,可以取值
}// 打印结果: 5.5

2.3:void*指针变量和 普通指针一样可以通过 等于0或者 NULL来初始化,以此表示一个空指针

void *pv = 0;

void  *pv2 = NULL;

cout<

cout<

2.4: 当void* 指针作为 函数的输入和输出时,表示可以接受任意类型输入指针和输出任意类型的指针


// void* 类型指针解析#include
using namespace  std;void* test(void* a) {return a;
}int main() {static int a = 5;int* pi = &a;cout << "变量a的地址:" << &a << endl;cout << pi << endl; // 输出变量a的地址cout << test(pi) << endl;cout << test((void*)pi) << endl;}变量a的地址:00C2C000
00C2C000
00C2C000
00C2C000

3:应用场景

3.1:函数传参时不确定类型,或者支持多类型的传参


void function(int dataType, void* data) {// 根据dataType的不同值,进行不同的转换switch (dataType) {case 0:int* a = (int*)data;case 1:char* a = (char*)data;...}

3.2 函数的繁殖值不考虑类型(不关心大小的时候)

void * memcpy(void *dest, const void *src, size_t len);
void * memset ( void * buffer, int c, size_t num );

memcpy和memset 对外接收任何类型的指针,这样是合理且必要的,因为这是内存操作函数,是对bit 进行操作,考虑数据的类型事没有任何意义的 。

同样的,malloc函数只关注你要多大内存,你申请到这个内存之后,至于你怎么使用划分是你自己的事情,但是你需要显示的表明你是怎么划分的,所以这里需要将 void* 类型转化为具体的数据类型

int *a=NULL;
 
a=(int *)malloc(sizeof(int));//返回的是void*,所以赋值给其他指针类型要强转一下

3.3  在函数调用过程中的使用作为输入输出参数也非常好用,可以灵活使用任意类型的指针,避免只能使用固定类型的指针。 

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...