C、C++ void 指针理解

75 阅读2分钟

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");

	  }  

	  

	}

参考链接:www.cnblogs.com/gjsun/p/177…