1. No, a is an array of 2 array of 4 int. a[0] is an array of 4 int.
2. Both &a and &a[0] point to the starting memory address of the array. Note that &a and &a[0] have different types so you can't compare them with ==.
Can you actually point to directly to elements of an array like that? I thought you could only reference the first element, and then perform some arithmetic to point to consecutive elements
Of course you can reference elements this way. It's the typical way actually. Pointer arithmetic also works fine but so as indexing.
There is no such thing as level-1 and level-2 pointers. In C/C++ this would mean pointer to something. Sometimes this something is also a pointer so you have a pointer to a pointer (not level-2 pointer).
-a is a pointer to pointer to int. (The name of the array is a pointer)
-&a is a the address of the previous pointer so it's a pointer to a pointer to a pointer of int (start getting confusing)
-a[0] is like dereferencing a so it's a pointer to int. It's equivalent to *a
-&a[0] is the address of the previous pointer so it's again pointer to pointer to int. Equals a.
-a[0][0] is like dereferencing a pointer and again dereferencing it's contents (the content must be a pointer also) so you just get the first element of array a this way.
-&a[0][0] is the address of the first element of a so it's equivalent to a[0].
In order to understand all this mambo jumbo crap, focus on thinking what you are (de)referencing. If you have a pointer you can take it's address (a pointer to this pointer that is) or it's element (the pointed value). The first is done by preceding an & and the second by an *. Similarly you can continue with the former pointer to pointer to get all the above pointers and variables.
a is a pointer to pointer to int. (The name of the array is a pointer)
You fail to difference between pointers and arrays. arrays are not pointers. It's just that they easily convert to pointers in many cases if you try to use them as such.
1 2 3 4 5 6 7
void foo(int**){}
int main()
{
int a[2][4] = {{1,2,3,4},{5,6,7,8}};
foo(a);
}
error: cannot convert 'int (*)[4]' to 'int**' for argument '1' to 'void foo(int**)'
Array is a pointer in the same sense that a double is an int. There is an implicit conversion from the former to the latter, and that conversion loses information.
Array is a pointer in the same sense that a double is an int.
I don't think the analogy is exactly the same. Name of arrays basically can't be used differently. I don't know for example what's the use of an array "before" conversion.
double on the other hand was sometime completely different. Anyway the point that I do not
difference between pointers and arrays
make some sense.
As I get it arrays is just a pointer to the first element with the extra issue that there (may) exist other adherent elements. Of course one interesting thing about arrays it's that they not know about their size.
Example:
1 2
int a[5]; //array of 5 elements;
int *b = &a[1]; //b could be considered an array of 4 elements without problem.
Of course someone could just state that there is an implicit conversion blah blah. Maybe there is but what was before being converted?
Name of arrays basically can't be used differently.
You can pass arrays to functions that expect references to arrays, such as std::begin() and std::end() and std::swap(), you can use them directly in range for loops, you can use them as arguments to operator&, sizeof, typeof, decltype, etc. This isn't C where it's just & and sizeof.