我成功地在堆中分配了一个指向 3 个整数的数组的指针,但我仍然不明白对数组的访问是如何工作的?

I succeeded allocating a pointer to an array of 3 ints in the heap, but I still don't understand how does the access to the array work?

经过几次试验,我成功地分配了一个指向 3 int 数组的指针,其中包含一个 新表达式 。在下面的代码片段中,我首先展示了这个指针在堆栈中的使用,然后展示了经过多次试验后堆分配的位置。

#include <iostream>
int main()
{
    // First, pointer p to an array of 3 int's in the stack.

    int a[3] = { 10, 11, 12 };
    int(*p)[3] = &a;
    std::cout << **p << "  " << *(*p + 1) << "  " << *(*p + 2) << '\n';
    std::cout << p[0][0] << "  " << p[0][1] << "  " << p[0][2] << '\n';

    // Second, the pointer is allocated on the heap.

    int(**q)[3] = new (int(*)[3]) {p};

    // That's what I've got after several trials. But I'm still trying to
    // understand how does the access to the array work in the next two lines of code?

    std::cout << ***q << "  " << ***q + 1 << "  " << ***q + 2 << '\n';
    std::cout << q[0][0][0] << "  " << q[0][0][1] << "  " << q[0][0][2] << '\n';
}

代码打印

10  11  12
10  11  12
10  11  12
10  11  12

live example

编辑 @A.S.H。在我的代码中发现错误,在他下面的评论中。我正在进行必要的更改以阐明示例。

#include <iostream>
int main()
{
    // First, pointer p to an array of 3 int's in the stack.

    int a[3] = { 100, 200, 300 };
    int(*p)[3] = &a;
    std::cout << **p << "  " << *(*p + 1) << "  " << *(*p + 2) << '\n';  // Change here
    std::cout << p[0][0] << "  " << p[0][1] << "  " << p[0][2] << '\n';

    // Second, the pointer is allocated on the heap.

    int(**q)[3] = new (int(*)[3]) {p};
    std::cout << ***q << "  " << *(**q + 1) << "  " << *(**q + 2) << '\n';  // Change here
    std::cout << q[0][0][0] << "  " << q[0][0][1] << "  " << q[0][0][2] << '\n';
}

通过这些更改,代码更加清晰。如果我之前知道这个错误,我就不会提出这个问题。谢谢@A.S.H。供您输入。

q是指向数组的指针。所以如果你取消引用它两次,你会得到一个数组。如果您再次取消引用它,它会进行数组到指针的转换以提供指向该数组第一个元素的指针 (10),然后再取消引用,因此您会得到 10。加法的优先级低于一元前缀运算符,所以 ***q + 1 表示 (***q) + 1,所以它是 11.

q[0][0][0] 相当于解引用 q 3 次,因为 q[i] 就意味着 *(q+i)。对于 q[0][0][1],它与解引用两次然后返回数组索引 1 处的元素相同,因此它是 11.