C语言void指针的用法

C语言void指针的用法在使用 C 语言进行开发的过程中 经常会遇到 void 这样一个特殊的指针 容易被新手忽视 实际上 void 非常强大 下面举几个比较常见的例子 1 用作泛型 接收任意数据类型指针 void 用于指向特定地址 而无需关心这个地址上存放着什么类型的数据 例如常见的 memcpy 等函数就用到 void 函数原型如下 void memcpy void des void src size tn 此处的 void des 和 void src 可以接收任意类型的数据类型指针 既然是内存拷贝 入参就不应

在使用C语言进行开发的过程中,经常会遇到void*这样一个特殊的指针,容易被新手忽视,实际上void*非常强大。下面举几个比较常见的例子。

1. 用作泛型,接收任意数据类型指针

void*用于指向特定地址,而无需关心这个地址上存放着什么类型的数据。例如常见的memcpy等函数就用到void*,函数原型如下:

void *memcpy(void *des, void *src, size_t n)

此处的void *des和void *src可以接收任意类型的数据类型指针,既然是内存拷贝,入参就不应该限制传入什么类型的指针,逻辑上十分合理。

2. 动态内存申请与释放

动态内存申请函数返回值一般都是void*,如果申请成功则返回的是申请的内存块的首地址,申请失败则返回一个空指针NULL,NULL相当于(void *)0。C库的malloc函数原型如下:

void *malloc(size_t size) 

一般申请完内存之后会与指针类型强制转换一起使用,如下所示。

typedef struct { char *name; int age; ... }animal, *animal_t; animal_t dog = (animal_t )malloc(sizeof(animal)); if(!dog) { printf("malloc failed\n"); }

3. 私有数据关联

利用void*关联私有数据是一种常见的编程技巧,这种技巧在Linux中广泛存在。以下截取了宋宝华老师的《Linux设备驱动开发详解》的一小段代码,保留了核心部分。struct file结构体中有一个void* private_data,在globalmem_open中使用struct file的private_data指针记录对应的设备的地址,那么后续只要获取到了file结构体指针,也就可以通过file结构体指针的private_data成员来间接获取到对应的设备了,例如globalmem_read函数。

#define DEVICE_NUM 10 struct globalmem_dev { struct cdev cdev; ... }; struct globalmem_dev *global_devp; static int __init globalmem_init(void) { int i; /* 分配设备号等操作 */ ... /* 为global_devp申请DEVICE_NUM个globalmem_dev内存大小的空间 */ global_devp = kzalloc(sizeof(struct globalmem_dev) * DEVICE_NUM, GFP_KERNEL); if(!global_devp ) return -1; for(i = 0; i < DEVICE_NUM; i++) { /* 将申请的DEVICE_NUM个设备添加到字符设备节点中 */ globalmem_setup_cdev(global_devp + i, i); } return 0; } static int globalmem_open(struct inode *inode,struct file *filp) { /* 在globalmem_setup_cdev中已经添加到字符设备节点了 */ struct globalmem_dev *dev = container_of(inode->i_dedv, struct globalmem_dev, cdev); filp->private_data = dev; } static ssize_t globalmem_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos) { struct globalmem_dev *dev = filp->private_data; }

不仅仅是Linux,在一些RTOS中也常常能见到void*的身影,例如线程或定时器在创建时,往往需要一个入口函数或超时回调函数,而这些函数的入参往往就是一个void*,必要时对这些void*加以利用,能起到简化代码、减小耦合等作用。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/213309.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午6:08
下一篇 2026年3月18日 下午6:08


相关推荐

  • 几款常用UML建模工具解析[通俗易懂]

    本节向大家介绍几款常用UML建模工具,UML是个好东西,但是过分的依赖于UML也不是一件好事,因为有时候它会把简单的东西复杂化。请看下面详细介绍。常用UML建模工具UML不算是个新名词,但是实际中还是用得很少(可能是因为都是做小项目的原因吧,大项目就用得多了).UML是个好东西,但是过分的依赖于UML也不是一件好事,因为有时候它会把简单的东西复杂化.即使是代码的优良结构和可重用性也不能

    2022年4月6日
    132
  • 消息称阿里 Qwen 管理调整出炉,周靖人代管千问模型一号位

    消息称阿里 Qwen 管理调整出炉,周靖人代管千问模型一号位

    2026年3月13日
    1
  • move_uploaded_file

    move_uploaded_file

    2021年9月19日
    43
  • 智慧小区智能化视频监控系统建设方案

    智慧小区智能化视频监控系统建设方案在每栋住户楼的各个立面布设红外枪式摄像机,监测高空抛物等不文明行为。通过实时视频监控+人工巡更方式,极大提升社区防控效率。

    2022年10月18日
    5
  • 代码走查总结[通俗易懂]

    代码走查总结[通俗易懂]什么是代码走查代码走查就是,项目开发人员在一起,对代码进行讨论。项目开发人员可以向大家阐述代码的逻辑和写代码的思路!在向别人阐述的时候,会发现做自己写的代码出现的一些问题。收获我进行代码阐述的时候,是按照功能来进行的,在阐述的过程中,我能感觉到我自己是清楚这个逻辑思路的,但是说着说着就发现了一些说不通的地方,还有一些不合理的地方。这让我突然想到了,之前出现的一个bug但是,死活不知道是…

    2025年7月31日
    8
  • 虚拟串口模拟器和串口调试助手使用教程「建议收藏」

    虚拟串口模拟器和串口调试助手使用教程「建议收藏」虚拟串口(虚拟COM端口),应该很多人都知道,也就是一种模拟物理串行接口的软件。它完全复制了硬件COM接口的功能,并且将被操作系统和串行应用程序识别为真实端口。以前的电脑,基本标配都包含一个串口。但现在的电脑,基本都没有配置串口了。如果要使用串口的功能,基本就要用一个USB转串口的硬件模块。现实生活中,虚拟串口用处很多。比如:你的应用程序检测串行输入数据的时候,方便调试。还比如:多个有应用程序之间使用串口通信。虚拟串口软件推荐:强大的虚拟串口软件串口调试助手软件有很多,随便选一个自己

    2022年6月12日
    58

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号