抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

C/C++中Void *的理解

2022-11-06 16:44:35

部分内容来自 C++中的void*理解

1. void *是什么?

语言中,*类型就是指针类型。比如 int *p,double q,虽然是不一样的指针,但是大小却一样sizeof§ == sizeof(q),其实很容易理解,因为他们都是同一种类型类型的。C语言是强类型的语言。对类型的区分十分严格。那这两个有什么不同点吗?有,+1就不同了,如下:

b0c4a1d07ca401008676cb3ca8d7c98c

也就是对于一个指针而言,如果我们在前面规定了它的类型。那就相当于决定了它的“跳跃力”。“跳跃力”就比如说上面图中int跳了4个字节,但是double跳了8个字节。

基于这样的理解,我要对void *下定义了:void * 是一个跳跃力未定的指针

2. void*详解

2.1 void可以指向任何类型的地址,但是带类型的指针不能指向void的地址

正常来说如果两个指针类型不一样的话,两个指针变量是不可以直接相等的。例如int* a, float* b,假如令a = b,会直接发生编译错误,而void指针可以等于任何类型的指针。但是反过来不可以,也就是说一个有类型的指针不能指向一个void类型的变量(哪怕此时void*变量已经指向了一个有类型的地址)。

float f = 5.5;
float* pf = &f;
void* pv = pf;
float* pf2 = pv;//编译错误,有类型的指针变量不能指向void*变量

2.2 void*指针只有强制类型转换以后才可以正常取值

int main(int argc, const char * argv[]) {

    float f = 5.5;
    float* pf = &f;
    void* pv;
    pv = pf; //这句是可以的
    
    cout<<*pv<<endl;  //编译错误,这样直接对pv取值是错误的
    cout<<*(float*)pv<<endl;  //强制类型转换后可以取值
    return 0;
}

在令pv = pf后,此时pv和pf指向的是同一个地址,值相同,但是两者的类型是不一样的。pf作为浮点型指针,是可以直接取到浮点数的,但是pv必须要强制类型转换以后才可以取值,也就是说一个void*的指针必须要经过强制类型转换以后才有意义。

int main(int argc, const char * argv[]) {

    float f = 5.5;
    float* pf = &f;
    void* pv;
    pv = pf;
    cout<<*(float*)pv<<endl;  //强制类型转换后可以取值,值为5.5
    cout<<*(int*)pv<<endl; //强制类型转换,值为1085276160
    cout<<(int)(*(float*)pv)<<endl;//取值后再次类型转换,值为5
    return 0;
}

如果把一个指向float的值的void指针,强制转换成int*也是不对的。也就是说地址保存了什么样的变量,就要转化成哪种类型的指针,否则就会出错。

2.3 void*指针变量和普通指针一样可以通过等于0或者NULL来初始化,表示一个空指针

void* pv = 0; 
void* pv2 = NULL;
cout<<pv <<endl; //值为0x0
cout<<pv2<<endl; //值为0x0

**2.4 当void*指针*作为函数的输入和输出*时,表示可以*接受任意类型的输入指针和输出任意类型的指针*

void* test(void* a)
{
    return a;
}
int main() {
    static int a = 5;
    int* pi = &a;
    cout<<pi<<endl;              //值为0x100001060
    cout<<test(pi)<<endl;        //值为0x100001060
    cout<<test((void*)pi)<<endl; //值为0x100001060
}

如果函数的输入类型为void*,在调用时由于是值传递,所以函数实际接收到的应该就是一个地址值。这个值可以是任意类型。

int a = 5;
int* pi = &a;
void* test()
{
    return pi; 
}
int main() {
    cout<<test()<<endl;        //值为0x100001060
}

输出时同样也是值传递,因此可以输出任意类型指针指向的地址。

评论吧



本站总访问量为 访客数为

鲁 ICP 备 20018157 号-1
Copyright 2021 - 2022 sizaif. All Rights Reserved