万能指针:void * 指针

背景

最近看到void 类型的指针不知道该怎么处理,特别学习一下。

适用语言

C/C++当中都可以使用,但就目前认知水平,C当中用的较为普遍一些。

void* 指针的机制

指针从某种程度上来说,无非就是一个地址,它的类型只是用于说明数据结构的(指针所指向的内存空间要按什么数据类型来解释,那指针变量就该是相对应的数据类型)。例如 int 型指针告诉编译器该地址处存放着的 4 字节的数据要按照 int 型数据来解释,double 型指针高速编译器接下来的 8 字节按照 double 型数据解释。

使用void* 指针的必要性

根据上部分对指针机制的解释,如果按照常规的指针使用方法,指针在使用中,会暴露存放在其所指向的内存空间的数据的数据类型信息,如果所使用的数据类型是基础类型还好,如果是复杂的自定义的结构体,那相当于将所定义在结构体里面的具体变量信息,都会呈现给使用者了。故:

为C语言程序的稳定和安全计,使用void * 将不公开的数据隐藏起来,避免外界调用者访问和修改它,使外界调用可以不用关心指针变量所指向的空间的具体数据结构

为C语言程序指针的灵活运用计,任意指针都可以使用 void 指针传递,并且编译器不会报出“类型不匹配”相关的警告

void* 指针的使用

由于 void 类型是一个特殊的类型,常被称作“空类型”,C语言中没有 void 类型的变量,所以在遇到 void 指针时,编译器根本不知道如何解释接下来的内存,甚至编译器都不知道接下来多少内存属于它。故而,在C语言中,遇到 void * 指针时,如果需要访问它指向的内存,需要重新指定类型(也就是指针类型的强制转换),否则就会报错。

即要想正确使用传进来的 void* 型指针时,要将其先转换为正确的数据类型,这其实要求程序员事先了解 void* 指针指向的数据结构,否则就没法使用 void * 指针。

如:

void CMDJob(void* pMsgBody void* pPData)
{
    char *pToPrint = NULL;
    pToPrint = (char*)pMsgBody;
    printf("%c\n",pToPrint);
}

必定是有权限编辑这个函数的程序员知道pMsgBody其实是个char类型,才可以在接收到这个void* 类型的指针后,进行强转,也不耽误使用了,否则,要是转换成了int类型或者其他类型,就得不到需要的值了。

尤其是,当指针是指向一个结构体的时候,那更需要用void进行传递了:

typedef struct SCMD
{
    char     SCMDname;
    double   SCMD_data;
    int      len;
    bool     flag;
    long     period;
}
T_SCMD;

void processscmd(T_SCMD* pRecvData)//直接用指向结构体的指针传递,会暴漏所指向数据的属性
{
    ...
}

void processscmd(void* pRecvData)//安全,无暴漏
{
    ...
}

void*指针的典型属性

void的指针大小和int*,float*一样,都是4字节

void* 指针并不指向任何确切的类型(但不可理解为void* 指向任何类型),当指向的地址上的内存的类型被指定时,void* 指针在调用时被强制转型为该类型的指针。

void指针的操作比其他指针要少,只能和另一个指针比较,主要用于向函数传递或者被函数返回,给同类型的指针赋值,

void* 指针不能操作它所指向的对象,不能对void 类型进行解引用,不能对它进行算数操作。

猜你喜欢

转载自blog.csdn.net/qq_17846375/article/details/114476708