c++ 指针的解引用

发布时间:2024年01月19日

解引用是通过指针访问指向的内存位置上存储的值的过程。你可以使用解引用运算符(*),放在指针变量的前面来实现这一过程

解引用一个指针

int x = 10;
int* p = &x; // p 是一个指向 x 的指针
int y = *p;  // y 被赋值为 x 的值,*p 为解引用 p ,解引用p得到x的值
//变量 y 将被赋值为 5,因为 *p 返回了 p 所指向的值。

改变指针指向的值

通过解引用来修改指针指向的内存中的值
*p = 20; // 现在 x 的值为 20
//解引用 p 并给它赋一个新值,将会改变原本 p 所指向的内存位置的内容,因此 x 的值将变为 20。

解引用数组的指针

int arr[5] = {1, 2, 3, 4, 5};
int* ptr = arr; // ptr 指向数组 arr 的第一个元素
int first = *ptr;     // first 为 1,即 arr[0] 的值
int second = *(ptr+1); // second 为 2,即 arr[1] 的值
//ptr+1 移动到数组的第二个元素,然后被解引用

解引用与 const

当处理 const 数据或指针时,解引用的行为需要小心。如果你有一个指向 const 数据的指针,你可以解引用它来读取数据,但不能通过解引用的指针来修改数据
确保对指针的处理与其指向的数据的 const 质量相匹配是防止未定义行为的关键。应注意 const 指针(指针本身是 const 的)和指向 const 数据的指针之间的区别。
const int constantValue = 100;
const int* ptrToConst = &constantValue;

int value = *ptrToConst; // 合法的读操作
*ptrToConst = 200; // 非法的写操作,编译时会出错

解引用多级指针

int x = 10;
int* p = &x; // p 是一个指向 x 的指针
int** pp = &p; // pp 是指向指针 p 的指针
int zz = *p;  // 解引用一次得到 p
int z = **pp;  //解引用两次得到 x; z 被赋值为 p 指向的值,即 x 的值
//pp 是一个多级指针,即指针的指针。解引用两次 **pp 可以获取 pp 指向的指针所指向的值,即 x 的值

解引用与数组 subscript 符号的等效性

解引用指针与数组下标(subscript)符号是紧密相关的。对于数组类型的指针,解引用加上某个偏移量和使用下标访问数组元素的结果是等效的。这种关系是由指针算术和数组访问的语义所定义的。
*(ptr + index) 与 ptr[index] 等价
需要注意的是:尽管解引用与数组下标在功能上等价,但在某些情况下,显式使用指针算术可能会让代码变得更难理解,因此通常建议使用数组下标来提高代码的可读性。此外,谨慎处理指针和数组下标的边界情况,以避免出现越界访问,这可能会导致未定义的行为。
int third = ptr[2]; // 直接使用数组 subscript 方式访问第三个元素
int fourth = *(ptr+3); // 使用指针算术和解引用方式访问第四个元素
//这里 third 为 3,因为 ptr[2] 相当于解引用了指向第三个元素的指针。同样, fourth 为 4,因为 ptr+3 移动到第四个元素,然后被解引用
解引用 void 指针
void 指针是一种特殊类型的指针,可以指向任何类型的数据。然而,你不能直接解引用一个 void 指针,因为没有具体的数据类型信息告诉编译器该如何解释所指向的内存内容。
如果你确实需要解引用一个 void 指针,你需要先将它转型为指向具体类型的指针
解引用 void 指针是非法的,因为 void 类型表示没有类型的值,且编译器无法知道如何解释指向的内存块的大小。
void* ptrToVoid = &x;
//*ptrToVoid = 20; // 错误:不允许解引用 void 指针

void* voidPtr = &value;
int* intPtr = static_cast<int*>(voidPtr);
int dereferencedValue = *intPtr; // 合法的解引用操作

通过指针成员访问操作符解引用

对于指向对象(例如结构体或类)的指针,你可以用箭头操作符(->)来解引用并访问其成员
struct Point {
    int x;
    int y;
};

Point p = {10, 20};
Point* ptr = &p;

int x = ptr->x; // 解引用并访问成员 x,得到 10
int y = ptr->y; // 解引用并访问成员 y,得到 20

注意事项

当解引用指针时,十分重要的是确保指针是指向有效内存的。如果指针是 nullptr、一个未初始化的指针、一个已经释放的内存块的指针,或者指向一个不再有效的对象(对象生命周期已经结束),那么解引用它将导致未定义的行为,可能引发程序崩溃或其它错误。在实际使用中,应该避免出现未定义行为的情况。

文章来源:https://blog.csdn.net/weixin_43779276/article/details/135625064
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。