C++:指针:void*指针(跳跃力未定的指针)

2023-10-27

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

#include<iostream>
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<iostream>
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<<pv<<endl;  //打印值为 0x0;

cout<<pv2 <<endl;  //打印值为 0x0;

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


// void* 类型指针解析

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++:指针:void*指针(跳跃力未定的指针) 的相关文章

  • C 编程 - 文件 - fwrite

    我有一个关于编程和文件的问题 while current NULL if current gt Id Doctor 0 current current gt next id doc current gt Id Doctor if curre
  • “构建”构建我的项目,“构建解决方案”则不构建

    我刚刚开始使用VS2010 我有一个较大的解决方案 已从 VS2008 成功迁移 我已将一个名为 Test 的控制台应用程序项目添加到解决方案中 选择构建 gt 构建解决方案不编译新项目 选择构建 gt 构建测试确实构建了项目 在失败的情况
  • WCF RIA 服务 - 加载多个实体

    我正在寻找一种模式来解决以下问题 我认为这很常见 我正在使用 WCF RIA 服务在初始加载时将多个实体返回给客户端 我希望两个实体异步加载 以免锁定 UI 并且我想利用 RIA 服务来执行此操作 我的解决方案如下 似乎有效 这种方法会遇到
  • 嵌套接口:将 IDictionary> 转换为 IDictionary>?

    我认为投射一个相当简单IDictionary
  • 在 Windows 窗体中保存带有 Alpha 通道的单色位图会保存不同(错误)的颜色

    在 C NET 2 0 Windows 窗体 Visual Studio Express 2010 中 我保存由相同颜色组成的图像 Bitmap bitmap new Bitmap width height PixelFormat Form
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 在 ASP.NET 5 中使用 DI 调用构造函数时解决依赖关系

    Web 上似乎充斥着如何在 ASP NET 5 中使用 DI 的示例 但没有一个示例显示如何调用构造函数并解决依赖关系 以下只是众多案例之一 http social technet microsoft com wiki contents a
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • 覆盖子类中的字段或属性

    我有一个抽象基类 我想声明一个字段或属性 该字段或属性在从该父类继承的每个类中具有不同的值 我想在基类中定义它 以便我可以在基类方法中引用它 例如覆盖 ToString 来表示 此对象的类型为 property field 我有三种方法可以
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable
  • 哪种 C 数据类型可以表示 40 位二进制数?

    我需要表示一个40位的二进制数 应该使用哪种 C 数据类型来处理这个问题 如果您使用的是 C99 或 C11 兼容编译器 则使用int least64 t以获得最大的兼容性 或者 如果您想要无符号类型 uint least64 t 这些都定
  • 如何防止用户控件表单在 C# 中处理键盘输入(箭头键)

    我的用户控件包含其他可以选择的控件 我想实现使用箭头键导航子控件的方法 问题是家长控制拦截箭头键并使用它来滚动其视图什么是我想避免的事情 我想自己解决控制内容的导航问题 我如何控制由箭头键引起的标准行为 提前致谢 MTH 这通常是通过重写
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐

  • 服务器修改编码格式,设置服务器编码格式

    设置服务器编码格式 内容精选 换一换 在异构计算架构中 昇腾AI处理器与CPU通过PCIe总线连接在一起来协同工作 Host CPU所在位置称为主机端 Host 是指与昇腾AI处理器所在硬件设备相连接的X86服务器 ARM服务器或者Wind
  • java基础之集合

    集合 基础里的重头戏来喽 一 集合概述 集合和数组的区别 概述 集合是java中用来存放多个 引用数据类型 数据的容器 它是解决了数组的一些弊端的一个多数据容器 他有 的操作集合的方法 比如增加和删除方法 java中集合的体系使用接口和类进
  • RAC重建OCR/Voting disk遇到的一些故障

    author skate time 2010 05 09 我的测试环境 母系统 win2003虚拟软件 vmware3 2 1guest系统 centos4 7oracle db oracle10 2 1 以下是我在重建rac的ocr vo
  • 全球分布式云大会:AntDB超融合流式实时数仓,打造分布式数据库新纪元

    日前 全球分布式云大会北京站在北京金茂万丽酒店举办 亚信科技AntDB数据库受邀参会 会上技术负责人北陌发表以 AntDB超融合流式实时数仓 打造分布式数据库新纪元 为主题的演讲 通过分享AntDB在数据库前沿技术的研发实践 与参会嘉宾一起
  • springboot的安全性

    如何实现 Spring Boot 应用程序的安全性 为了实现 Spring Boot 的安全性 我们使用 spring boot starter security 依赖项 并且必须添加安全配置 它只需要很少的代码 配置类将必须扩展WebSe
  • BM8 链表中倒数最后k个结点

    struct ListNode int val struct ListNode next ListNode int x val x next nullptr class Solution public 代码中的类名 方法名 参数名已经指定
  • 代码块11

    import numpy as np rot matrix 0 5 np asarray 1 1 1 1 1 1 1 1 np sqrt 2 np sqrt 2 0 0 0 0 np sqrt 2 np sqrt 2 判断矩阵是否正交 pr
  • flash开发ipa踩的坑

    1 xcode中找到libclang rt ios a添加到AIRSDK lib aot lib中 2 ios 打包ane 要添加 如果是 tbd则当dylib一样处理 去AIRSDK lib aot stub里面看有没有 dylib需要在
  • C++类和动态内存分配

    1 动态内存和类 静态数据成员在类声明中声明 在包含类方法的文件中初始化 初始化时使用作用域运算符来指出静态成员所属类 如果静态成员是整形或枚举型const 则可以在类声明中初始化 在构造函数中使用new来分配内存时 必须在相应的析构函数中
  • 高阶源码分析:ConcurrentHashMap

    高阶源码分析 ConcurrentHashMap 一 文章导读 这部分内容让大家读懂ConcurrentHashMap源码的底层实现从而在工作中合理去使用他并且在面试中能做到游刃有余 主要内容如下 核心构造方法 核心成员变量 put方法过程
  • html中图片左右切换,超简单的图片左右切换滑动

    网上看过很多图片左右切换滑动的效果 不过大都是使用插件实现 插件虽方便 但是对于新手的学习并不是最好的 本文使用jquery这个由原生的JavaScript封装的库 用最简短的代码实现此功能 效果预览如下图 代码部分 直接复制代码便可使用
  • c++数组长度函数length_数据结构-数组

    数组 在数组末尾插入元素 push let numbers 3 4 7 0 1 6 numbers push 11 14 返回数组长度 在数组开头插入元素 unshift numbers unshift 11 14 返回数组长度 手写一个
  • 带有Spring Boot和Spring Cloud的Java微服务

    朋友不允许朋友写用户身份验证 厌倦了管理自己的用户 立即尝试Okta的API和Java SDK 在几分钟之内即可对任何应用程序中的用户进行身份验证 管理和保护 Java是开发微服务架构时使用的一种很棒的语言 实际上 我们行业中的一些知名人士
  • 解决pip的ImportError: cannot import name ‘PackageFinder‘ from ‘pip._internal.index‘ (xxxx)

    问题描述 使用pip时报错 ImportError cannot import name PackageFinder from pip internal index xxxx 问题解决 直接更新 curl https bootstrap p
  • Kotlin 中初始化块、初始化的顺序、lateinit延迟初始化详解

    前些天发现了一个蛮有意思的人工智能学习网站 8个字形容一下 通俗易懂 风趣幽默 感觉非常有意思 忍不住分享一下给大家 点击跳转教程 1 初始化块 初始化块可以设置变量或值 以及执行有效性检查 如检查传给某构造函数的值是否有效 初始化块代码会
  • linux 回收站

    参考 28条消息 Linux中为其配置 回收站 刘瑜澄的博客 CSDN博客 rm命令将文件移至回收站 可跟多个参数 多个文件 文件夹 被移入回收站 设置了移入回收站不覆盖同名文件 如同名文件a txt按照123的顺序移入回收站 回收站中的文
  • React路由

    路由组件 Switch
  • 激活函数之logistic sigmoid函数介绍及C++实现

    logistic sigmoid函数 logistic sigmoid函数通常用来产生Bernoulli分布中的参数 因为它的范围是 0 1 处在 的有效取值范围内 logisitic sigmoid函数在变量取绝对值非常大的正值或负值时会
  • csharp:Learn how to post JSON string to generic Handler using jQuery in ASP.Net

  • C++:指针:void*指针(跳跃力未定的指针)

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