简体   繁体   中英

How do pointers to 2d arrays work in C++?

I'm pretty new to C++ and I've been playing around with the language to try to understand most of it. I recently started to look into 2d arrays, and I totally understand arrays of pointers to arrays (created on the heap), but I have a harder time with the code below.

int arr2d[3][2] = {
    {1, 2},
    {3, 4},
    {5, 6}
};

I understand that in memory, it acts as a single dimensional array, but I don't understand how pointers work with them. I tried assigning arr2d to an int pointer, but it doesn't work. So I tried with the auto keyword.

int* a = arr2d; // throws an error
auto a = arr2d; // auto = int(*a)[2]

When hovering over "a" in Visual Studio, it gives me the type int(*a)[2]. This is what I really don't understand.

I have looked for documentation but I can't find this syntax anywhere. Can someone please explain to me what that pointer type does and how I can recreate it with any n-dimensional array?

Thank you!

This is actually very interesting and, the more you learn about C++ the more completely irrelevant you find it becomes in all but rare situations.

int arr2d[3][2] = {
    {1, 2},
    {3, 4},
    {5, 6}
};

So here you have an identifier arr2d and that identifier has a type:

array of arrays

Now the type array in C++ relates to a contiguous block of objects. So you have a contiguous block of contiguous blocks .

However, when you use the identifier in an expression the rules of C++ say it decays into a pointer to the first element of the array for which it is type array (there is a subtle distinction between an array and a type called "array") .

So when you do this:

auto a = arr2d;

Well the identifier a is now a pointer because arr2d has decayed into a pointer to the first element of the 2D Array you originally created. But what is the type of the pointer?

It is a pointer to the first element of an array of arrays . But the first element of an array of arrays is an array - so it is a pointer to an array . How is that written in C++ syntax?

Like this:

int (*)[2]; // see the right-left-rule

C++ syntax can be a dark art and none of it quite so dark as the declaration of types. The complexity of it is hidden for simple situations like an int but shows its metal when things get complicated.

int (*)[2]; // see the right-left-rule

This means a pointer (now go right) to an array of 2 elements (now go left) of type int .

C++ types are declared onion like, unwrapping right to left to allow a unified syntax capable of declaring anything from an int to a function returning a function pointer to a function that returned a pointer to an array of function pointers... etc.

See: right-left-rule .

Incidentally you could avoid decaying to a pointer to array by using this syntax:

auto a = &arr2d; // get the address of the whole 2D array

Your IDE should show something like:

int (*)[3][2]; // pointer to array-of-array-of-int

You would access it like this:

(*a)[0][0] = 1; // dereference pointer to access 2D array it points to

But I suspect a better remedy to your problem is to use std::array . That will behave more predictably.

std::array<std::array<int, 2>, 3> arr2d = {{
    {1, 2},
    {3, 4},
    {5, 6}
}};

auto a = &arr2d;

Now a is type std::array<std::array<int, 2>, 3>*

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM