对指向数组的指针解引用

Dereferencing a pointer to an array?

本文关键字:指针 引用 数组      更新时间:2023-10-16

指带有注释的行:

  • 为什么在示例中添加括号来打印数组的所有内容?

示例打印"one",然后打印垃圾。

#include <iostream>
int main() {
    const char* a[3] = { "one", "two", "three" };
    const char*(*p)[3] = &a;
    for(int i = 0; i < 3; i++) {
        std::cout << *p[i] << std::endl; // this line
    }
    return 0;
}

std::cout << (*p)[i] << std::endl;

p是一个指向3个元素的数组的指针,如下所示:

┌─────┬─────┬─────┐
│     │     │     │
└─────┴─────┴─────┘
   ^
   └─ p

注意,它指向整个数组,而不是其中的单个元素。

由于运算符优先,表达式*p[i]被视为*(p[i])(相当于*(*(p + i)))。这意味着您正在索引指向数组的指针。例如,如果您执行p[1],则将指针移动到"下一个"数组并尝试对其解引用:

┌─────┬─────┬─────┐
│     │     │     │
└─────┴─────┴─────┘
                     ^
                     └─ p + 1
正如我们所看到的,那里什么也没有,你会得到未定义的行为。然而,当您执行(*p)[i](相当于*((*p) + i))时,您要确保首先发生解引用。解引用给出了数组本身,然后可以通过数组到指针的转换将其隐式转换为指向数组第一个元素的指针。所以你得到的是:
┌─────┬─────┬─────┐
│     │     │     │
└─────┴─────┴─────┘
   ^
   └─ *p

在这种情况下,指针指向数组元素,而不是整个数组。如果对(*p)[1]进行索引,您将得到:

┌─────┬─────┬─────┐
│     │     │     │
└─────┴─────┴─────┘
         ^
         └─ (*p) + 1

这给了你一个有效的const char*,然后可以由cout输出。

操作符优先级。如果没有()运算符,[]将首先被调用,其结果将是dereferenced。对于() -首先将dereference,然后调用操作符[]

操作符优先级

数组选择比解引用具有更高的优先级,因此从编译器的角度来看,它实际上是:

*(p[i])
        #include <iostream>
        using namespace std;       
        int main() {

            int arr[5] = {1,2,3,4,5};
            int *p=arr;

            int intgerSize=sizeof(int);

            for(int k=0;k<5;k++)

            {  
                cout<<"arr ["<<k<<"] "<<*(p+(k*sizeof(int)/intgerSize));  
                cout<<"  "<<(p+(k*sizeof(int)/intgerSize));
                cout<<"  "<<p+k<<"n"; 
            }`enter code here`
            return 0;
        }
OUTPUT:- 
arr [0] 1 0x7ffd180f5800  0x7ffd180f5800
arr [1] 2 0x7ffd180f5804  0x7ffd180f5804
arr [2] 3 0x7ffd180f5808  0x7ffd180f5808
arr [3] 4 0x7ffd180f580c  0x7ffd180f580c
arr [4] 5 0x7ffd180f5810  0x7ffd180f5810