4. void 类型的指针
在 C 语言中,有这样一个用于描述数据类型的关键字 void,它不同于 int、double 等能够描述详细的内存结构,正好相反,它表示没有类型的类型(或者叫空类型)。
void 的字面含义是空白的、空的。
void 类型的三个作用:
- 作为指针的类型,表示不关心指针指向地址的数据类型,仅用于保存内存地址。
- 作为函数的返回类型(后面会讲)。
- 作为函数的参数列表(后面会讲)。
有时候我们只需要一个指针来保存一个变量的内存地址,但是并不关心这段内存中存储的数据是什么类型,这个时候我们可以用 void 类型的指针,即:void* 类型。
void 类型的变量声明的语法
void *变量名1, *变量名2, ...
说明:
- void 不能声明普通变量,只能用于声明指针类型的变量,如
void x;的类型声明是错误的。 void*类型的指针可以指向任何类型的指针,有时也叫通用指针。但要转到其它数据类型需要使用类型转换运算符进行强制类型转换。void*类型的指针通常只用来保存地址,不关心指向地址内的数据类型。void*类型的指针不能使用解引用运算符对内容进行访问。需要转化成其它类型的指针才能访问指向的数据。
示例:
// filename: void_pointer.c
#include <stdio.h>
int main(int argc, char *argv[]) {
char ch = 'a';
short s = 10;
int i = 1000;
// 声明三个 void* 类型的指针,用于保存不同类型变量的地址。
void *pv1 = &ch, *pv2 = &s, *pv3 = &i;
//打印三个变量的地址
printf("&ch:%p, &s:%p, &i:%p\n", &ch, &s, &i);
//打印三个void*类型的指针的值
printf("pv1:%p, pv2:%p, pv3:%p\n", pv1, pv2, pv3);
// 打印 void 类型的指针的占用的内存空间的大小
printf("sizeof(pv1):%ld\n", sizeof(pv1));
// 使用强制类型转换将 pv3 的值转换为 int* 类型的指针,饭后解引用
printf("int value at %p is %d\n", pv3, *((int*)pv3));
return 0;
}
运行结果如下:
weimingze@mzstudio:~$ gcc -o void_pointer void_pointera.c
weimingze@mzstudio:~$ ./void_pointer
&ch:0x7ffdbf5c9189, &s:0x7ffdbf5c918a, &i:0x7ffdbf5c918c
pv1:0x7ffdbf5c9189, pv2:0x7ffdbf5c918a, pv3:0x7ffdbf5c918c
sizeof(pv1):8
int value at 0x7ffdbf5c918c is 1000
根据打印结果,可见
- 各个 void* 类型的指针的值是各个变量的内存地址,与对应的变量的内存地址相同。
- void* 类型的指针占用的字节数也是 8 字节(也可能是4字节),它和普通的指针的区别就在于不关心指向数据的类型。
- 对 pv3 使用强制类型转换可以再次获取 i 变量的值。
实验
- 改写上述示例,使用 一个指针
void * pv1来依次保存各个变量地址数据。并打印依次打印指针的值。