返回介绍

6.8.2 void 类型指针

发布于 2025-04-11 22:33:02 字数 2132 浏览 0 评论 0 收藏 0

第 4 章中,在定义函数时,如果没有返回值,就会将返回值类型定义为 void,如果函数没有参数,也可以在参数列表中使用 void。在 C 语言中,void 表示空类型。因此,C 语言不允许定义 void 类型的变量,但是,C 语言允许定义 void 类型的指针。例如:

void *pv;

上述语句定义了一个 void 类型的指针变量 pv。

C 语言中,任何类型的指针都可以被隐式地转换为 void 类型的指针。也就是可以直接将一个其他类型的指针赋值或初始化给 void 类型的指针。例如:

int a = 10;
int *pi = &a;
void *pv = pi;

以上语句首先定义了一个 int 类型变量 a,并初始化为 10;接着,定义一个 int 类型指针变量 pi,并将变量 a 的内存地址初始化给 pi;最后定义一个 void 类型的指针变量 pv,并将 pi 的值初始化给 pv。这是没问题的,编译器可以将一个 int 类型的指针 pi 的值转换成一个 void 类型的指针初始化给 pv。因此,指针 pv 也保存着变量 a 的内存地址。

那可不可以对 pv 进行解引用,访问并获取变量 a 的值呢?例如:

printf("%d\n", *pv);

编译程序时,会有如下的警告和错误信息:

warning: dereferencing 'void *' pointer  printf("%d\n", *pv);
error: invalid use of void expression

警告信息内容为:在 printf 函数中,我们对 void 类型的指针进行了解引用;而错误信息内容为:无效地使用了 void 表达式。也就是说,不能对 void 类型的指针进行解引用。

对指针进行解引用时,会根据指针的类型来确定所访问的内存字节数和数据格式。由于 void 是空类型,没有内存大小和数据格式信息,因此,无法对 void 类型的指针进行解引用。

使用时,需要将 void 类型的指针再次转换为 int 类型的指针,才能正确访问变量 a。例如:

printf("%d\n", *(int*)pv);

在 pv 前面加上类型转换运算符进行强制类型转换,得到一个 int 类型的指针,对这个 int 类型指针再进行解引用就可以访问到变量 a,并打印输出值。

编译运行程序,结果如下:

10

void 类型的指针,通常都是作为函数的参数来使用,这样做的好处是,可以将任何类型对象的指针传递给它,并且 void 类型的指针可以像 char 类型的指针一样来进行指针的移动或指针的运算。即 void 类型的指针每移动一次,其保存的内存地址值就会增加 1 字节,而 void 类型的指针与某整数相加,所产生的新指针的内存地址就是原指针的内存地址与整数相加的和。

在“string.h”头文件中,有几个以“mem”开头的函数,都是以内存为操作对象的功能函数。例如 memset 函数可以以字节为单位设置指定大小的内存块数据,它的函数原型如下:

void* memset(void* buffer, int ch, size_t count);

函数第一个参数 buffer 表示所需设置内存块的起始地址;第二个参数 ch 是一个整数值,内存块的各字节都会被设置为该值;第三个参数 count 是一个无符号整数,表示内存块的大小,以字节为单位。结合起来看,memset 函数的功能是将一个从 buffer 地址开始的、count 字节大小的内存块中的各字节都设置为整数值 ch。函数返回值与 buffer 一样,同是该内存块的起始地址。

可以使用 memset 函数非常方便地将一个数组中的所有元素值全部设为 0。程序代码如下:

程序代码中,首先定义了一个长度为 5 的 int 类型数组 arr,并对数组进行了初始化。接着使用 memset 函数对数组进行设置,它会将数组 arr 看成是一个内存块,内存块的起始地址是 arr,内存块大小为数组的大小,内存块的各字节都会被设置为 0。因此,通过循环打印数组元素时,所有的数组元素全部都变为 0 了。

编译运行程序,结果如下:

0 0 0 0 0

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。