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

【C++】详解 void*

文章目录

    • 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. 在函数调用过程中的使用作为输入输出参数也非常好用,可以灵活使用任意类型的指针,避免只能使用固定类型的指针。

相关文章:

【C++】详解 void*

文章目录 1. void *是什么&#xff1f;2. void*详解3. 和void的区别4. 应用场景4.1 函数传参时不确定类型&#xff0c;或者要支持多类型的传参&#xff1b;4.2 当函数的返回值不考虑类型指关心大小的时候 5. 总结 今天看到一段代码&#xff0c;觉得非常有意思。 void* say_hell…...

Linux家目录变成了-bash-4.2$

Linux家目录变成了-bash-4.2$ Mark a workarround: 使用root用户&#xff0c;执行cp -a /etc/skel/. /home/zookeeper/&#xff08;不是root用户也可以&#xff09; 其中/home/zookeeper/目录是对应自己的家目录地址~ 若有帮到你&#xff0c;记得点赞&#xff0c;收藏呀…...

Python和SQLite游标处理多行数据

如果您需要处理多行数据&#xff0c;使用游标或其他适当的方法是更好的选择。以下是一些处理多行数据的方法&#xff1a; 使用游标&#xff1a;游标可以逐行处理查询结果&#xff0c;这对于大量数据或需要逐行处理的场景非常有用。以下是一个使用Python和SQLite的游标示例&…...

安全测试之PHP 漏洞全解

PHP 漏洞全解(一)-PHP的攻击方式 针对 PHP 的网站主要存在下面几种攻击方式: 1、命令注入(Command Injection) 2、eval 注入(Eval Injection) 3、客户端脚本攻击(Script Insertion) 4、跨网站脚本攻击(Cross Site Scripting, XSS) 5、SQL 注入攻击(SQL injection) 6、跨网站…...

【bug-maven】(一)java: 错误: 不支持发行版本 5 (二):java: 错误: 无效的源发行版:15

【bug-maven】&#xff08;一&#xff09;java: 错误: 不支持发行版本 5 &#xff08;二&#xff09;&#xff1a;java: 错误: 无效的源发行版&#xff1a;15 &#xff08;一&#xff09;java: 错误: 不支持发行版本 5 报错截图&#xff1a; 出错原因&#xff1a; 打开Projec…...

git命令大全(附使用步骤+注释)

下面有具体使用步骤 git status 查看git状态 git add 提交到暂存区 git commit -m 提交到本地仓库&#xff0c;添加注释 git log 查看日志 git clone 克隆远程仓库 git reset&#xff0c;指定文件识 可以将暂存区的文件回退到工作区 git checkout指定文件’ 可以进行工作区还原…...

【论文阅读】Progressive Spatio-Temporal Prototype Matching for Text-Video Retrieval

资料链接 论文链接&#xff1a;https://openaccess.thecvf.com/content/ICCV2023/papers/Li_Progressive_Spatio-Temporal_Prototype_Matching_for_Text-Video_Retrieval_ICCV_2023_paper.pdf 代码链接&#xff1a;https://github.com/imccretrieval/prost 背景与动机 文章发…...

python --- 类与对象(二)

类属性与方法 类的私有属性 __private_attrs&#xff1a;两个下划线开头&#xff0c;声明该属性为私有&#xff0c;不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。 类的方法 在类的内部&#xff0c;使用 def 关键字来定义一个方法&#xf…...

任正非说:华为以前还出现过可笑的工号文化,看官大官小的指令

你好&#xff01;这是华研荟【任正非说】系列的第33篇文章&#xff0c;让我们聆听任正非先生的真知灼见&#xff0c;学习华为的管理思想和管理理念。 一、要把可以规范化的管理都变成扳铁路道岔&#xff0c;使岗位操作标准化、制度化。 来源于任正非先生2003年的讲话《在理性与…...

用Python舞动数据的魔力:探索数据分析的艺术之路

用Python舞动数据的魔力&#xff1a;探索数据分析的艺术之路 前言什么是Python数据分析Python介绍数据分析介绍Python和数据分析的关系 python数据分析的作用金融领域社交媒体领域电子商务领域医疗领域物流和供应链管理领域 Python数据分析教材 前言 打开招聘网站&#xff0c;…...

iOS 让界面元素的文字随着语言的更改而变化——本地化文字跟随

在我的 App 内置的设置中&#xff0c;修改了语言&#xff0c;这时需要让当前界面的文本跟着改变语言。 解决方法是&#xff1a;添加一个观察者&#xff0c;观察 localize 本地语言的通知&#xff0c;然后一有变化就调用自定义的方法执行操作。&#xff08;而设置中其实是改变了…...

Xcode15更新内容

参考博客&#xff1a; 【WWDC 2023】Xcode 15 更新内容 文章目录 1. xcode15起&#xff0c;项目内创建的图片可以使用点语法访问2.2. UIKit项目也可以使用预览功能3. Xcode新增标签功能4.Log分类 1. xcode15起&#xff0c;项目内创建的图片可以使用点语法访问 2.2. UIKit项目也…...

【数据集标注制作】视频剪切标注1——类DarkLabel软件

视频标注 用于从视频中标注数据&#xff0c;用于YOLO网络的目标检测。旨在实现单次鼠标标注能生成多张被标注图像&#xff0c;实现数据集快速制作&#xff01; 从视频中&#xff0c;通过鼠标框选指定区域&#xff0c;形成掩码box鼠标选定区域后&#xff0c;根据设定的成像尺寸…...

一体化HIS医疗信息管理系统源码:云HIS、云电子病历、云LIS

基于云计算技术的B/S架构的HIS系统&#xff0c;为医疗机构提供标准化的、信息化的、可共享的医疗信息管理系统&#xff0c;实现医患事务管理和临床诊疗管理等标准医疗管理信息系统的功能。系统利用云计算平台的技术优势&#xff0c;建立统一的云HIS、云病历、云LIS&#xff0c;…...

NSSCTF逆向题解

[SWPUCTF 2021 新生赛]简简单单的逻辑 直接把key打印出来&#xff0c;然后整理一下result&#xff0c;让key和result进行异或 key[242,168,247,147,87,203,51,248,17,69,162,120,196,150,193,154,145,8] data[0xbc,0xfb,0xa4,0xd0,0x03,0x8d,0x48,0xbd,0x4b,0x00,0xf8,0x27,0x…...

广域网加速的作用:企业为什么需要广域网加速?

由于局域网与广域网之间巨大的带宽鸿沟&#xff0c;通过增加带宽来满足膨胀的流量需求是不切实际的。 并且广域网带宽成本较高&#xff0c;增加广域网带宽对任何企业都意味着巨大的成本负担。这些使得控制 管理广域网带宽使用成为必需。 企业为什么要加速广域网? 对重要的企…...

SQL SERVER Inregration Services-OLE DB、Oracle和ODBC操作

OLE DB链接器 OLE DB插件下载&#xff1a;https://learn.microsoft.com/zh-cn/sql/connect/oledb/download-oledb-driver-for-sql-server?viewsql-server-ver16 配置OLE DB Connection Manager 在点击“新建”时&#xff0c;会弹出警告信息“不支持指定的提供程序&#xff0…...

尚硅谷大数据项目《在线教育之实时数仓》笔记006

视频地址&#xff1a;尚硅谷大数据项目《在线教育之实时数仓》_哔哩哔哩_bilibili 目录 第9章 数仓开发之DWD层 P041 P042 P043 P044 P045 P046 P047 P048 P049 P050 P051 P052 第9章 数仓开发之DWD层 P041 9.3 流量域用户跳出事务事实表 P042 DwdTrafficUserJum…...

Linux-源码安装go

使用go 1.14 版本 #wget https://golang.org/dl/go1.14.15.linux-amd64.tar.gz #tar zxvf go1.14.15.linux-amd64.tar.gz #mv go /usr/local/ #vim /etc/profile export GOROOT/usr/local/go export GOBIN$GOROOT/bin export GOPKG$GOROOT/pkg/tool/linux_amd64 export GO…...

如何检测小红书账号是否被限流?哪些原因会导致账号被限流?

hi&#xff0c;同学们&#xff0c;本期是第5期AI运营技巧篇&#xff0c;文章底部准备了粉丝福利&#xff0c;看完后可领取&#xff01; 最近好多新手学员运营小红书账号&#xff0c;可能会遇到这样的问题&#xff1a;发布的内容小眼睛少得可怜&#xff1f;搜索不到自己的笔记&…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道

文/法律实务观察组 在债务重组领域&#xff0c;专业机构的核心价值不仅在于减轻债务数字&#xff0c;更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明&#xff0c;合法债务优化需同步实现三重平衡&#xff1a; 法律刚性&#xff08;债…...

PydanticAI快速入门示例

参考链接&#xff1a;https://ai.pydantic.dev/#why-use-pydanticai 示例代码 from pydantic_ai import Agent from pydantic_ai.models.openai import OpenAIModel from pydantic_ai.providers.openai import OpenAIProvider# 配置使用阿里云通义千问模型 model OpenAIMode…...