泛型指针 void * 的妙用

指针的概念

在理解泛型指针(也称之为万能指针)之前,我们需要了解指针的概念,最常见的说法就是指针就是地址。下面有这样一个定义:

int *p;

上面的定义我们可以知道, p 称之为指针变量,而并不是指针,而 *p 我们才称之为指针。
所以也就有了如下的操作:

int *p;
int a = 10;
p = &a;
printf("The value of p is:%p\n",p);
printf("The value of *p is:%d\n",*p);

上述的操作简单地说明了指针的用法,即将 a 的地址赋值给了 p 指针变量,所以 p 里面所存储的内存地址处的内存就是 p 所指向的内存。通过 *p 解引用就可以获得指针变量指向的内存的值。因此上述代码第一个输出的是 a 的地址,而第二行输出的是 10
另外上述也有简单的写法,就是这样:

int a = 10;
int *p = &a;
printf("The value of p is:%p\n",p);
printf("The value of *p is:%d\n",*p);

理解上述也不难,只需知道对于 p 来讲,我们只是定义了一个int * 类型的指针变量,然后对 p 进行了赋值。
一个对于初学比较容易懵的是下面这样的一个概念:

int a = 10;
int *p = &a;
*p = 20;
printf("The value of *p id:%d\n",*p);
printf("The value of a is:%d\n",a);

第一条的输出语句我想大家都能明白,因为将指针赋值为 20 ,那输出自然是 20 ,但是对于第二条输出语句可能会误以为还是 10 ,因为我们也没有在程序中看到哪里改变了 a 的值。正确答案是 a 的值是 20 。因为第二条语句 p 已经指向了 a 的地址,虽然我们改变了 *p 的值,但是对于 p 的值没有改变,所以说 p 所指向的内存地址没变,但是内存地址里面的内容已经变了,而 a 的地址和 p 的值是一样的。所以 a 的值也就相应发生了改变。

泛型指针

介绍了指针的大致概念后,我们回过头来想,指针的类型是什么,因为变量是有类型的,那么相应的指针也应该有类型。所以有了如下定义:

int *p;
char *cp;
float *fp;

p 的类型就是 int * ,cp 的类型就是 char * ,fp 的类型就是 float * ,我们知道不同类型的变量在赋值时,需要进行强制转换,对于指针来说也是这样,但是指针相对于变量来讲,有一个特殊的类型,就是 void * ,我们称之为泛型指针,同样也被我们称之为万能指针。
在引入万能指针的应用之前,我们看一个初学者都会接触过的例子,就是数据的交换:

void swap(int *p1,int *p2)
{
	int temp;

	temp = *p1;
	*p1 = *p2;
	*p2 = temp;
}

但是这个数据交换存在一个局限性,只能应用于整型数据的交换,那么如何设计一个能够适用于任何数据类型的交换程序呢,这里就需要适用我们之前提到的泛型指针。

int swap(void *p1,void *p2,int size)
{
	void *temp;

	if((temp = malloc(size)) == NULL)
		return -1;
	memcpy(temp,p1,size);
	memcpy(p1,p2,size);
	memcpy(p2,temp,size);
	free(temp)
	return 0;
}

上面就是对于 void * 的应用,能够接收不同类型的数据进行交换,当然里面也应用了 memcpy() 函数,memcpy 可以复制任何一段数据,它的作用是将数据从内存中的一个地方拷贝到另一个地方。对于上述程序中的 malloc 是用于给 temp 分配一个内存,防止其成为野指针,最后再将其分配的内存释放掉。

发布了19 篇原创文章 · 获赞 6 · 访问量 1720

猜你喜欢

转载自blog.csdn.net/weixin_42616791/article/details/105205136