1.void类型指针简介
- void类型的指针又被称为泛型指针,通用型指针
- void类型的指针:指针指向的内存地址中的数据的类型未知
- 其他所有类型的指针都可以转换为void类型的指针,而且不需要强制类型转换(编译器会隐式/自动类型转换)
- void类型的指针也可以转换为任意类型的指针,需要强制类型转换(实际上不需要,但是强制类型转换会增加代码的可读性,比如使用malloc函数的时候)
- void类型的指针不可以直接解引用(dereference),强制类型转换之后才可以正常访问void指针指向的内存单元
int main() {
int a = 10;
// 指针p指向变量a, 但是p的类型仍然是void
void* p = &a;
printf("%d\n", *p); // 错误,因为p是void类型的,编译器无法判断p可以访问几个字节
printf("%d\n", *(int*)p); // 正确,将p强制转换为int类型的指针,编译器就指导p指向的数据占用四个字节
return 0;
}
2.探讨void类型指针为什么具有通用性?
2.1 以以下代码为例,通过void类型的指针p,可以正常访问不同类型的变量,因此,void类型的指针被成为泛型指针/通用型指针
2.2 除了void类型的指针之外,其他类型的指针不可以实现这种特性
#include <stdio.h>
int main(int argc, char* argv[]) {
char a = 'H';
int b = 10;
float c = 2.8;
double d = 9.7;
void* p;
// p saves the address of variable a
p = &a;
printf("a = %c\n", *(char*)p);
// p saves the address of variable b
p = &b;
printf("b = %d\n", *(int*)p);
// p saves the address of variable c
p = &c;
printf("c = %f\n", *(float*)p);
// p saves the address of variable d
p = &d;
printf("d = %lf\n", *(double*)p);
return 0;
}
3.void指针的应用:使用一个泛型指针可以遍历不同类型的数组!
#include <stdio.h>
enum type {
CHAR,
INT,
DOUBLE
};
void generic_function(enum type t, void* ptr);
int main(int argc, char* argv[]) {
// void type pointer / generic pointer / general-purpose pointer
char ch_arr[] = "Hello";
int int_arr[] = {3, 1, 2};
double db_arr[] = {3.14, 2.7, 1.58, 20.4};
// print the first element for each different type array
generic_function(CHAR, ch_arr);
generic_function(INT, int_arr);
generic_function(DOUBLE, db_arr);
return 0;
}
void generic_function(enum type t, void* ptr) {
// t的类型指导泛型指针ptr如何访问数组(强制类型转换不同)
switch(t) {
case CHAR:
printf("The first element is: %c\n", ((char*)ptr)[0]);
break;
case INT:
printf("The first element is: %d\n", ((int*)ptr)[0]);
break;
case DOUBLE:
printf("The first element is: %lf\n", ((double*)ptr)[0]);
break;
default:
printf("No type matched!\n");
}
}