IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言 void和void *(无类型指针) -> 正文阅读

[C++知识库]C语言 void和void *(无类型指针)

void 关键字

void的字面意思是“无类型”,void *则为“无类型指针”,void *可以指向任何类型的数据。

void几乎只有“注释”和限制程序的作用,因为从来没有人会定义一个void变量,让我们试着来定义:

void a; 

这行语句编译时会出错,提示“illegal use of type ‘void’”。不过,即使void a的编译不会出错,它也没有任何实际意义。

void真正发挥的作用在于:

  1. 对函数返回的限定
    当函数不需要返回值时,必须使用void限定。例如: void func(int, int)
  2. 对函数参数的限定
    当函数不允许接受参数时,必须使用void限定。例如:int func(void)

void 指针

void的意思就是“无类型”,void指针则为“无类型指针”,void指针可以指向任何类型的数据。所以void指针一般被称为通用指针或者泛指针,或者叫做万能指针。

void指针使用规范

1、void指针可以指向任意类型的数据,即可用任意数据类型的指针对void指针赋值。例如

int  *pint   ;
void *pvoid  ;      //它没有类型,或者说这个类型不能判断出指向对象的长度
pvoid = pint ;      //只获得变量/对象地址而不获得大小,但是不能 pint=pvoid;

在C语言中,可以把任何类型的指针(包括函数指针)赋值给void*指针而无须进行强制类型转换。

在C++中,对这个转换做了更严格的限制:只有非常量指针才能赋值给void*指针。
C++示例代码:

const char pp[10] = {0};
const char* str = "aaa";

void* pv = NULL;
pv = pp;//错误
pv = str;//错误 不能将常量指针赋值给void *指针

2、如果要将pvoid赋给其他类型指针,则需要强制类型转换如:

pint = (int *)pvoid;     //转换类型也就是获得指向变量/对象大小

注意:在C++编译器中必须转换 pint = (int*)pvoid 否则报错; 但在C编译器中可以写成 pint = pvoid;

3、void指针在强制转换成具体类型前,不能解引用(即取内容的意思)

*pvoid    //错误

要想复引用一个指针,或者使用“->”运算符复引用一部分,都要有对于指针指向的内存的解释规则。
  例如,int *p;
那么,当你后面复印用p的时候,编译器就会把从p指向的地址开始的四个字节看作一个整数的补码。
因为void指针只知道指向变量/对象的起始地址,而不知道指向变量/对象的大小(占几个字节)所以无法正确引用

4、void指针不能参与指针运算,除非进行转换。
按照ANSI(AmericanNationalStandardsInstitute)标准,不能对void指针进行算法操作,即下列操作都是不合法的:

void*      pvoid ;
pvoid++          ; //ANSI:错误
pvoid+=1         ; //ANSI:错误

ANSI标准之所以这样认定,是因为它坚持:进行算法操作的指针必须是确定知道其指向数据类型大小的。
例如:

int*     pint;
pint++       ; //ANSI:正确

pint++的结果是使其增大sizeof(int)。

但是大名鼎鼎的GNU(GNU’s Not Unix的缩写)则不这么认定,它指定void * 的算法操作与char * 一致。
因此下列语句在GNU编译器中皆正确:

pvoid++      ; //GNU:正确
pvoid+=1     ; //GNU:正确

pvoid++的执行结果是其增大了1。
  在实际的程序设计中,为迎合ANSI标准,并提高程序的可移植性,我们可以这样编写实现同样功能的代码:
(type*)vp++; //等价于:vp=vp+sizeof(type) type为任意数据类型

void * pvoid      ;
(char*) pvoid++    ; //ANSI:正确;GNU:正确
(char*) pvoid+=1   ; //ANSI:错误;GNU:正确

GNU和ANSI还有一些区别,总体而言,GNU较ANSI更“开放”,提供了对更多语法的支持。但是我们在真实设计时,还是应该尽可能地迎合ANSI标准。

void指针的应用

当进行纯粹的内存操作的时候,或者传递一个指向未定类型的指针时,可以使用void指针;
典型的如内存操作函数memcpy和memset的函数原型分别为:

void * memcpy(void *dest,constvoid * src,size_tlen);
void * memset(void * buffer,intc,size_tnum);

这样,任何类型的指针都可以传入memcpy和memset中,这也真实地体现了内存操作函数的意义,因为它操作的对象仅仅是一片内存,而不论这片内存是什么类型。
注意memcpy和memset函数返回的也是void*类型。

由于void * 可以和任何指针直接做变换,除了函数指针外,在C编译器下,我们知道malloc函数的返回类型是void*,所以下面2句是等价的

 int *p =(int*)malloc(100*sizeof(int));
 int *p =malloc(100*sizeof(int));

但在C++编译器下,第二句由于没有强制转换将报错。

参考鸣谢:
https://blog.csdn.net/weixin_30268071/article/details/97432128

https://blog.csdn.net/qq_29924041/article/details/54882135

https://blog.csdn.net/qq_38916259/article/details/88105739

https://blog.csdn.net/guo_guo_cai/article/details/78144364

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 07:31:54  更:2021-07-28 07:34:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/29 3:10:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码