关于void*的解释

关于void*

指针的类型不过是解释数据的方式不同罢了,这样的道理也可用于很多场合的强制类型转换,例如将int类型指针转换为char型指针,并不会改变内存的实际内容,只是修改了解释方式而已。而void 是一种无类型指针,任何类型指针都可以转为void,它无条件接受各种类型。

而既然是无类型指针,那么就不要尝试做下面的事情:
1.解引用
2.算术运算

由于不知道其解引用操作的内存大小,以及算术运算操作的大小,因此它的结果是未知的。是未知的东西就会导致结果是随机的或者导致程序崩溃。

#include <stdio.h>
int main(void)
{
    int a = 10;
    int *b = &a;
    void *c = b;
    *c;
    return 0;
}

编译警告如下:

warning: dereferencing ‘void *’ pointer

如何使用
既然如此,那么void有什么用呢?
实际上我们在很多接口中都会发现它们的参数类型都是void
,例如:

size_t read(int fd, void *buf, size_t count);
void *memcpy(void *dest, const void *src, size_t n);

为何要如此设计?因为对于这种通用型接口,你不知道用户的数据类型是什么,但是你必须能够处理用户的各种类型数据,因而会使用void*。void能包容地接受各种类型的指针。
也就是说,如果你期望接口能够接受任何类型的参数,你可以使用void
类型。
但是在具体使用的时候,你必须转换为具体的指针类型。例如,你传入接口的是int*,那么你在使用的时候就应该按照int*使用。

注意
使用void*需要特别注意的是,你必须清楚原始传入的是什么类型,然后转换成对应类型。例如,你准备使用库函数qsort进行排序:

void qsort(void *base,size_t nmemb,size_t size , int(*compar)(const void *,const void *));

它的第三个参数就是比较函数,它接受的参数都是const void*,如果你的比较对象是一个结构体类型,那么你自己在实现compar函数的时候,也必须是转换为该结构体类型使用。

举个例子,你要实现学生信息按照成绩比较:

typedef struct student_tag
{
    char name[STU_NAME_LEN];  //学生姓名
    unsigned int id;          //学生学号
    int score;                //学生成绩
}student_t;
int studentCompare(const void *stu1,const void *stu2)
{
  /*强转成需要比较的数据结构*/
    student_t *value1 = (student_t*)stu1;
    student_t *value2 = (student_t*)stu2;
    return value1->score-value2->score;
}

在将其传入studentCompare函数后,必须转换为其对应的类型进行处理。

总结
void*很强大,但是一定要在合适的时候使用;同时强转很厉害,但是一定要注意前后的类型是否真的能正确转换。

通俗地说void*:
这里有一片内存数据,我也不知道什么类型,给你了,你自己想怎么用怎么用吧,不过要用对奥!(即给你钱,你想怎么用就怎么用,但是你不能用到错误的地方,不能违法犯罪
我这里什么类型都能处理,你给我一片内存数据就可以了。

09-20 433
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值