I really want to understand pointers deeply before I move on because I read that it is very important! |
Pointers are important, but I wouldn't worry about the more arcane aspects for now. Array pointers, for example, do not turn up very often. Well, I've never seen them outside of exercises. (Aside: has anyone used them to solve a problem elegantly??)
1. What is the significance of "int (*p)[3] = b;"? |
It's just as the comment says. It's a pointer to an array of 3 ints.
Why they've defined p but then not used it, I have no idea. But this is how you could use an array pointer, though it's an overly involved way to solve this particular problem.
(Aside: in the code above, it's possible that lines 19 ad 20 should have been using p rather than b, esp. as line 19 is the same as line 9.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
#include <iostream>
using namespace std;
int main ()
{
int a[3] = {3, 4, 5}; // an array of 3 ints
int (*p)[3] = &a; // set p to the address of a
// write out array elems using pointer (note dereference)
for(int i = 0; 3 > i; ++i) {
cout << i << " = " << (*p)[i] << "\n";
}
return 0;
}
|
2. What is the difference between the two b's that are mentioned in the code? |
The first b (on line 6) is when the array is being defined.
The second b (on line 7) is the same variable. This time the value of p is being set to point at the first row of b.
Their example is rather confusing as they're defining a 2d array and then assigning it to a pointer to a 1d array, which works because of array decay. Which is part of the answer to your next question.
3. Why does the address of b the same as the value stored in b? |
The address isn't stored in b.
To C++ an array is a memory address; the address of the first element. So when you output an array using cout you get it's address. But the array has a different type to the address of the actual first element. That is, for
int arr[2] = {1, 2};
cout << arr;
and
cout << &arr[0];
will display the same value (as they refer to the same memory address) but are different types (the former is of type 'int const [2]' and the latter of type 'int *')
If the array is 1d then operator* will display the value of the first element (assuming istream knows how to deal with the type.) But as an array is not a pointer, what happens is that the array decays to a pointer and you dereference that resultant pointer, getting the value of the first element.
But if the array has more than one dimension, then the pointer the array decays to is not to a simple type, it's to an array with one less dimension (the first row, in the case of a 2d array). Dereferencing this pointer give you an array, and as the compiler sees an array as an address, that's what you'll see output (the address of the smaller array, which will be the same as the bigger array.)
The address of a 2d array, its first row, and the first element of the first row are all the same. But they have different types.
In case it helps, a 2d array of ints, for example, is really just a 1d array of 1d arrays of ints.
Not sure if this is making things clearer or more complicated.
Andy
PS For more info...
what is array decaying?
http://stackoverflow.com/questions/1461432/what-is-array-decaying