深入理解C语言的void*

2025-01-20 16:50
文章标签 语言 深入 理解

本文主要是介绍深入理解C语言的void*,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《深入理解C语言的void*》本文主要介绍了C语言的void*,包括它的任意性、编译器对void*的类型检查以及需要显式类型转换的规则,具有一定的参考价值,感兴趣的可以了解一下...

一、void* 的类型任意性

void* 是一种通用指针类型。它可以指向任意类型的数据。例如,它可以指向一个整数(int)、一个浮点数(float)、一个字符(char)或者一个结构体等。在C语言中,当你使用void*指针时,你不需要在编译时指定它将指向的数据类型。这使得void* 在一些China编程需要通用指针的场景下非常有用,比如在内存分配函数malloc中返回的就是void*类型的指针。因为malloc函数不知道用户将要分配的内存用于存储哪种类型的数据,所以它返回一个void*指针,用户可以根据自己的需要将其转www.chinasem.cn换为特定类型的指针。
例如:

void* ptr = malloc(10 * sizeof(int));
int* intPtr = (int*)ptr;  // 将void*指针转换为int*指针

在这个例子中,void*指针 ptr 可以指向分配的内存区域,然后通过类型转换将其转换为int*指针,用于存储整数数组。

二、编译器对 void* 的类型检查

编译时不做类型检查(针对void*本身)编译器在编译时不会对void*指针本身进行类型检查。因为 void* 表示“未知类型”的指针,编译器无法知道它实际指向的数据类型。所以,当你对void指针进行操作(如赋值等)时,编译器不会检查其指向的数据类型是否正确。例如,你可以将一个指向整数的指针赋值给void指针,也可以将一个指向字符的指针赋值给void*指针,编译器都不会报错。

int a = 10;
char b = 'k';
void* vp1 = &a;
void* vp2 = &b;

在这个例子中,vp1和vp2都是void*指针,分别指向了不同类型的变量a和b,编译器不会对这www.chinasem.cn种赋值操作进行类型检查。

三、需要显式类型转换

当你想要使用 void* 指针访问其中的某个值时,通常需要先将其转换为特定类型的指针,然后通过转换后的指针来访问值。在转换时,你需要明确指定目标类型,编译器会对转换后的指针类型进行检查。例如,如果你想通过 void* 指针访问一个整数的值,你需要先将其转换为 int* 指针。
例如:

void* vp = malloc(sizeof(int));
*(int*)vp = 20;  // 先将void*转换为int*,然后通过int*指针赋值

在这个例子中,vp是一个void*指针,指向分配的内存。在给这块内存赋值之前,需要先将其转换为int*指针。如果转换的目标类型和实际存储的数据类型不匹配,可能会导致运行时错误。 比如,如果这块内存实际上存储的是一个浮点数,而你将其转换为int*指针并访问,可能会得到错误的结果或者引发程序异常。编译器在转换时会检查语法是否正确(如是否有合适的类型转换操作),但对于类型转换的正确性(即是否符合程序的实际逻辑)主要依赖于程序员的正确使用。

占用的字节

一、32位系统
在32位系统中,void* 指针通常占据4个字节。这是因为32位系统中的内存地址空间是2的32次方(即android4GB),用4个字节(32位)就可以表示一个内存地址。例如,在一个32位的Windows系统或者32位的linux系统上,无论是void指针,还是其他类型的指针(如int、char*等),它们都占据4个字节。这4个字节存储的是一个内存地址,这个地址可以指向进程地址空间内的任意位置。

二、64位系统
在64位系统中,void* 指针通常占据8个字节。64位系统有更大的内存地址空间,理论上可以达到2的64次方字节。因此,需要用8个字节(64位)来表示一个完整的内存地址。在64位系统上,无论是 void* 指针,还是其他类型的指针,它们的大小都是8个字节。这使得64位系统能够访问更大的内存空间,支持更大的数据处理和更复杂的程序运行。

四、总结

通过我们上面的介绍, 我们发现 void* 在 C 语言中是经常使用的, 它主要有下面这几个方案:

  • 第一个方案就是作为结构体的字段, 这样我们可以去表示对应的范型字段
  • 函数的参数, 或者返回值, 但是我觉得这种最好少用, 因为导致对应的接口不够明确
  • 各种内存相关的函数, 这其实就是一个很奇妙的东西, 因为在操作系统级别, 我们并不知道这块内存到底是什么类型的变量

约定: 当我们在使用 void* 的时候, 我们最好弄清楚当前这个指针指向的信息, 可以通过明确的变量名来完成

到此这篇关于深入理解C语言的void*的文章就介绍到这了,更多相关C语言 void*内容请搜索China编程(www.cppcpythonns.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于深入理解C语言的void*的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:http://www.cppcns.com/ruanjian/c/697714.html
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1153144

相关文章

深入解析 Java Future 类及代码示例

《深入解析JavaFuture类及代码示例》JavaFuture是java.util.concurrent包中用于表示异步计算结果的核心接口,下面给大家介绍JavaFuture类及实例代码,感兴... 目录一、Future 类概述二、核心工作机制代码示例执行流程2. 状态机模型3. 核心方法解析行为总结:三

Go语言中使用JWT进行身份验证的几种方式

《Go语言中使用JWT进行身份验证的几种方式》本文主要介绍了Go语言中使用JWT进行身份验证的几种方式,包括dgrijalva/jwt-go、golang-jwt/jwt、lestrrat-go/jw... 目录简介1. github.com/dgrijalva/jwt-go安装:使用示例:解释:2. gi

Go 语言中的 Struct Tag 的用法详解

《Go语言中的StructTag的用法详解》在Go语言中,结构体字段标签(StructTag)是一种用于给字段添加元信息(metadata)的机制,常用于序列化(如JSON、XML)、ORM映... 目录一、结构体标签的基本语法二、json:"token"的具体含义三、常见的标签格式变体四、使用示例五、使用

Go语言使用slices包轻松实现排序功能

《Go语言使用slices包轻松实现排序功能》在Go语言开发中,对数据进行排序是常见的需求,Go1.18版本引入的slices包提供了简洁高效的排序解决方案,支持内置类型和用户自定义类型的排序操作,本... 目录一、内置类型排序:字符串与整数的应用1. 字符串切片排序2. 整数切片排序二、检查切片排序状态:

基于Go语言实现Base62编码的三种方式以及对比分析

《基于Go语言实现Base62编码的三种方式以及对比分析》Base62编码是一种在字符编码中使用62个字符的编码方式,在计算机科学中,,Go语言是一种静态类型、编译型语言,它由Google开发并开源,... 目录一、标准库现状与解决方案1. 标准库对比表2. 解决方案完整实现代码(含边界处理)二、关键实现细

如何合理管控Java语言的异常

《如何合理管控Java语言的异常》:本文主要介绍如何合理管控Java语言的异常问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍2、Thorwable类3、Error4、Exception类4.1、检查异常4.2、运行时异常5、处理方式5.1. 捕获异常

C语言中的常见进制转换详解(从二进制到十六进制)

《C语言中的常见进制转换详解(从二进制到十六进制)》进制转换是计算机编程中的一个常见任务,特别是在处理低级别的数据操作时,C语言作为一门底层编程语言,在进制转换方面提供了灵活的操作方式,今天,我们将深... 目录1、进制基础2、C语言中的进制转换2.1 从十进制转换为其他进制十进制转二进制十进制转八进制十进

$在R语言中的作用示例小结

《$在R语言中的作用示例小结》在R语言中,$是一个非常重要的操作符,主要用于访问对象的成员或组件,它的用途非常广泛,不仅限于数据框(dataframe),还可以用于列表(list)、环境(enviro... 目录1. 访问数据框(data frame)中的列2. 访问列表(list)中的元素3. 访问jav

spring IOC的理解之原理和实现过程

《springIOC的理解之原理和实现过程》:本文主要介绍springIOC的理解之原理和实现过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、IoC 核心概念二、核心原理1. 容器架构2. 核心组件3. 工作流程三、关键实现机制1. Bean生命周期2.

MySQL数据库约束深入详解

《MySQL数据库约束深入详解》:本文主要介绍MySQL数据库约束,在MySQL数据库中,约束是用来限制进入表中的数据类型的一种技术,通过使用约束,可以确保数据的准确性、完整性和可靠性,需要的朋友... 目录一、数据库约束的概念二、约束类型三、NOT NULL 非空约束四、DEFAULT 默认值约束五、UN