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

潍坊市住房和城乡建设局网站下载广州中学生网站制作

潍坊市住房和城乡建设局网站下载,广州中学生网站制作,企业形象vi设计公司,建站至尊文章目录 1. void *是什么?2. void*详解3. 和void的区别4. 应用场景4.1 函数传参时不确定类型,或者要支持多类型的传参;4.2 当函数的返回值不考虑类型指关心大小的时候 5. 总结 今天看到一段代码,觉得非常有意思。 void* say_hell…

文章目录

    • 1. void *是什么?
    • 2. void*详解
    • 3. 和void的区别
    • 4. 应用场景
      • 4.1 函数传参时不确定类型,或者要支持多类型的传参;
      • 4.2 当函数的返回值不考虑类型指关心大小的时候
    • 5. 总结

今天看到一段代码,觉得非常有意思。

void* say_hello(void* args)
{cout << "Hello World!" << endl;return 0;
}

void你经常看见,但是void*你能说出它具体什么意思吗?

1. void *是什么?

我们知道,C++是个强类型语言,指针类型的大小是相同的,即int*的大小与long long*的大小是相同的

sizeof(int*) == sizeof(long long*)

那既然大家都是指针类型,为什么还要分那么多的类别呢?换句话说*号前面的int与longlong这种具体类型的作用是什么呢?且看下面这张图:
img

在执行+1时,不同类型的指针移动的“距离”不同。如果我们在前面规定了它的类型。那就相当于决定了它的“跳跃力”。“跳跃力”就比如说上面图中int跳了4个字节,但是double跳了8个字节。

基于这样的理解,现在可以对void *下定义了:void * 是一个跳跃力未定的指针

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

2. void*详解

1️⃣:void*可以指向任何类型数据的地址,但是带类型的指针不能随意指向void*的地址:

float f = 5.5;
float* pf = &f;
void* pv = pf;
float* pf2 = pv;//编译错误,有类型的指针变量不能指向void*变量

2️⃣:void*指针只有强制类型转换以后才可以正常取值:

int main(int argc, const char * argv[]) {float f = 5.5;float* pf = &f;void* pv;pv = pf; //这句是可以的cout<<*pv<<endl;  //编译错误,这样直接对pv取值是错误的cout<<*(float*)pv<<endl;  //强制类型转换后可以取值return 0;
}

在令pv = pf后,此时pv和pf指向的是同一个地址,值相同,但是两者的类型是不一样的。pf作为浮点型指针,是可以直接取到浮点数的,但是pv必须要强制类型转换以后才可以取值,也就是说一个void*的指针必须要经过强制类型转换以后才有意义。

int main(int argc, const char * argv[]) {float f = 5.5;float* pf = &f;void* pv;pv = pf;cout<<*(float*)pv<<endl;  //强制类型转换后可以取值,值为5.5cout<<*(int*)pv<<endl; //强制类型转换,值为1085276160cout<<(int)(*(float*)pv)<<endl;//取值后再次类型转换,值为5return 0;
}

如果把一个指向float的值的void指针,强制转换成int*也是不对的。也就是说地址保存了什么样的变量,就要转化成哪种类型的指针,否则就会运行出错。

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

void* pv = 0; 
void* pv2 = NULL;
cout<<pv <<endl; //值为0x0
cout<<pv2<<endl; //值为0x0

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

void* test(void* a)
{return a;
}int main() {static int a = 5;int* pi = &a;cout<<pi<<endl;              //值为0x100001060cout<<test(pi)<<endl;        //值为0x100001060cout<<test((void*)pi)<<endl; //值为0x100001060
}

如果函数的输入类型为void*,在调用时由于是值传递,所以函数实际接收到的应该就是一个地址值。这个值可以是任意类型。

int a = 5;
int* pi = &a;void* test()
{return pi; 
}int main() {cout<<test()<<endl;        //值为0x100001060
}

3. 和void的区别

再让我们回头看初始的那段函数:

//返回了一个空指针
void* say_hello(void* args)
{cout << "Hello World!" << endl;return 0;
}//没有返回值
void say_hello(void* args)
{cout << "Hello World!" << endl;return;
}

其实两个函数实现的内容是一样的。但是void*返回类型的函数返回了一个空指针,而void型没有返回值。

4. 应用场景

4.1 函数传参时不确定类型,或者要支持多类型的传参;

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

4.2 当函数的返回值不考虑类型指关心大小的时候

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

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

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

同样的,malloc函数只关注你要多大的内存,你需要把它怎么划分是你的事情,但是你需要显式的表明你是怎么划分的。这里语法要求是必须的,void *类型转为其他类型必须强制类型转换。

5. 总结

  1. void*类型的指针其实本质就是一个过渡型的指针状态,必须要赋予类型(强制类型转换)才能正常使用。void *的范围较大,所以强制转换,使其进行范围缩小。
  2. 只能单向类型转换。void*可以转化成其他类型,但是有类型的不能转化成void*。
  3. 在函数调用过程中的使用作为输入输出参数也非常好用,可以灵活使用任意类型的指针,避免只能使用固定类型的指针。
http://www.yayakq.cn/news/20515/

相关文章:

  • 苏州网站建设企业网站制作保定seo外包服务商
  • 南宁品牌网站设计公司知识库管理系统
  • 云南建设投资控股集团有限公司网站用开源吗做的网站可以用吗
  • 北京++网站建设咨询顾问公司访问网页的流程
  • app开发分为哪几种滁州百度seo
  • 支付宝网站开发流程网站开发职业工资
  • 网站首页是什么河南建设厅官方网站
  • 网站做中英文切换济南市建设监理有限公司网站
  • 英文网站设计多少钱网站建设部门
  • 宝安区住房和建设局网站wordpress yzipicc
  • 西宁市网站建设高端网络平台建站流程
  • 页眉做的好的网站网站中新颖的功能
  • 做网站代理工作安全吗网站建设找单
  • windows 2008 网站wordpress 模板使用
  • 网站策划书撰写流程东莞网站建设公司服务平台
  • 梭子手做鱼网站家具设计师
  • 网站开发注意事项泸州网站建设多少钱
  • 网站开发的条件电商会学着做网站呢
  • 个人网站设计论文ppt怎样做3d动画短视频网站
  • 如何自建网站做外贸wordpress 首页跳转
  • 网站建设优化公司企业网站推广的方法
  • 网站建设调查回访表qq降龙是哪个公司开发的
  • 提供零基础网站建设教学网站建设方案设计书
  • 山东新华电脑学院学网站开发深圳域名空间
  • 网站开发公司气氛wordpress用户冻结
  • 帝国网站做图片轮播服装 多语言 网站源码
  • 如何做网站弹窗广告自学网站建设多久
  • 上海制作网站公司哪家好运城网站建设求职简历
  • 电子商务网站建设 以为例做分析报表的网站
  • 商标设计网站哪个好全国企业营业执照查询