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

void*在c语言中什么意思(非常详细)

讲解 C语言 void* 指针类型之前,先来看下面程序中的 swap() 函数,为了实现交换两个 int 类型的变量,必须向 swap() 函数中传入指向这两个 int 类型变量的指针:

void swap(int *x, int *y)
{int temp = *x;*x = *y;*y = temp;
}

但是,参数类型指定为 int*,使得函数 swap() 只能交换 int 类型的变量。如果我们想让 swap() 更加通用,能够交换不同类型的变量,那么该怎么办呢?

为了使 swap() 函数更加通用,我们可以使用 void* 指针。void* 指针是一种通用指针类型,可以指向任何类型的数据。

修改后的 swap() 函数如下:

void swap(void *x, void *y, int size)

上述代码中的参数 x 和 y 都是 void* 指针类型。

void* 指针是一种特殊的指针类型,可以指向任何数据类型的对象。与其他类型的指针不同,void* 指针不能直接对其指向的对象进行操作,因为编译器无法确定其指向的数据类型及其大小。

例如:

int n;
void *p = &n;  //  int *赋值给void *,仅保存首地址,丢失了数据类型
*p;            //  错误,无法确定数据类型和大小,因此无法取值
p + 1;         //  错误,无法确定数据类型和大小,因此无法进行加减运算

同时,上面的代码还增加了一个参数 size,这个参数表示要交换的内存块的大小,单位是字节。例如:如果需要交换 char 类型的数据,那么将 size 参数传递给 sizeof(char),也就是 1 字节;如果需要交换 double 类型的数据,那么将 size 参数传递给 sizeof(double),也就是 8 字节。

根据上述的内容,我们可以对 swap() 函数进行修改,使其能够交换不同类型的变量,代码如下:

/**
*  快速入门C语言 https://xiecoding.cn/c/
**/
#include <stdio.h>
void swap(void* x, void* y, int size)
{// 将指针转换为char *,单个字节操作内存char* pX = (char*)x;char* pY = (char*)y;char temp;for (int i = 0; i < size; i++){temp = pX[i];pX[i] = pY[i];pY[i] = temp;}
}
int main()
{double a = 3.0, b = 5.0;printf("a=%f b=%f\n", a, b);// 交换变量 a 和 bswap(&a, &b, sizeof(double));printf("a=%f b=%f\n", a, b);return 0;
}

运行结果为:

a=3.000000 b=5.000000
a=5.000000 b=3.000000

首先,swap() 函数将两个 void* 类型的指针 x 和 y 转换为 char*  类型的指针 pX 和 pY。这样做的原因是,char 类型的大小为 1 字节,这允许我们在后面的循环中逐字节地操作内存。

然后,我们定义了一个 char 类型的变量 temp,用于在交换过程中存储临时数据。

接着,我们使用一个 for 循环,从 0 到 size - 1,循环地交换两个内存块中的内容。循环的每次迭代都会执行以下操作:

  • 将 pX 指针指向的内存块中的第 i 个字节保存到 temp 中;
  • 将 pY 指针指向的内存块中的第 i 个字节复制到 pX 指向的内存块的第 i 个字节;
  • 将 temp 中的值复制到 pY 指向的内存块的第 i 个字节。

这样,在循环结束后,两个内存块中的内容就被完全交换了。只要提供了正确的内存块大小,这个函数就可以用于交换任意类型的数据。

需要注意的是,在使用 swap() 函数时,需要保证传入的内存块大小和实际数据类型的大小一致,否则可能会导致数据出错。

http://www.xdnf.cn/news/327403.html

相关文章:

  • scanpy处理:使用自定义 python 函数读取百迈客空间转录组数据(百创智造S1000)
  • 深度学习:智能车牌识别系统(python)
  • htop筛选进程时,出现重复进程
  • 德州仪器技术干货 | 48V 集成式热插拔电子保险丝:为现代 AI 数据中心高效供电
  • Python案例实战《水果识别模型训练及调用》
  • Linux 内核学习(7) --- 字符设备驱动
  • eFish-SBC-RK3576工控板CAN接口测试操作指南
  • leetcode 3341. 到达最后一个房间的最少时间 I 中等
  • Unity_JK框架【3】 事件系统的简单使用示例
  • 169.多数元素
  • openstack虚拟机状态异常处理
  • java集合菜鸟教程
  • 从 CodeBuddy Craft 到 edgeone-pages-mcp 上线算命网站的一次完整体验分享
  • 多语言网站的 UX 陷阱与国际化实践陷阱清单
  • 前端面试每日三题 - Day 27
  • 【Python】os模块
  • 使用 Gradio + Qwen3 + vLLM 部署 Text2SQL 多表查询系统
  • 【Prometheus】深入解析 Prometheus 特殊标签 `__param_<name>`:动态抓取参数的艺术
  • Android 数据持久化之数据库存储 Room 框架
  • 50个精选DeepSeek指令
  • ifconfig statistics
  • springboot使用阿里云OSS实现文件上传
  • 云上玩转Qwen3系列之二:PAI-LangStudio搭建联网搜索和RAG增强问答应用
  • C++初阶 —— 类和对象
  • C++ 中的 `it->second` 和 `it.second`:迭代器与对象访问的微妙区别
  • 如何延长电脑使用寿命?
  • Cadence 高速系统设计流程及工具使用二
  • 学习黑客 Linux用户管理
  • Linux理解文件fd
  • 热部署相关