tags:

views:

101

answers:

3

I realized that I had some confusion regarding the value of a dereferenced pointer, as I was reading a C text with the following code snippet:

int main() 
{ 
    int matrix[3][10];                 // line 3: matrix is tentatively defined
    int (* arrPtr)[10] = matrix;       // line 4: arrPtr is defined and initialize
    (*arrPtr)[0] = 5;                  // line 5: what is the value of (*arrPtr) ?

My confusion is in regards to the value of *arrPtr in the last line. This is my understanding upto that point.

Line 3, matrix is declard (tentatively defined) to be an array of 3 elements of type array of 10 elements of type int.

Line 4, arrPtr is defined as a pointer to an array of 10 elements of type int. It is also initialized as a ptr to an array of 10 elements (i.e. the first row of matrix)

Now Line 5, arrPtr is dereferenced, yielding the actual array, so it's type is array of 10 ints.

MY question: Why is the value of the array, just the address of the array and not in someway related to it's elements?

+1  A: 

The value of the array variable matrix is the array, however it (easily) "degrades" into a pointer to its first item, which you then assign to arrPtr.

To see this, use &matrix (has type int (*)[3][10]) or sizeof matrix (equals sizeof(int) * 3 * 10).

Additionally, there's nothing tentative about that definition.

Edit: I missed the question hiding in the code comments: *arrPtr is an object of type int[10], so when you use [0] on it, you get the first item, to which you then assign 5.

Pointers and arrays are purposefully defined to behave similiarly, and this is sometimes confusing (before you learn the various quirks), but also extremely versatile and useful.

Roger Pate
In the expression (*arrPtr)[0] = 5, given that the subscript operator [] requires a pointer as one of it's operands. Does *arrPtr satisfy that requirement?
ed mach
`*arrPtr` is an array (arrPtr points to an array and you dereference it), and you can use subscript on arrays. C calls `[]` array-subscripting and does require one operand to be a pointer---however, it relies on the arrays degrading, see 6.5.2.1/2 in the C standard (which explicitly says this): http://www.open-std.org/jtc1/sc22/wg14/www/standards.html
Roger Pate
Actually, the example in 6.5.2.1/4 should also help.
Roger Pate
I checked C standard and it does say if one operand is an "array object", it will be converted to a pointer to the initial element. So I guess that applies whether the "array object" is an actual array_Name OR a dereferenced array pointer. Thanks Roger.
ed mach
A: 

I think you need to clarify your question. If you mean what is the value of printf("%i", arrPtr); then it will be the address of the array. If you mean printf("$i",(*arrPtr)[0] ); then we've got a more meaty question.

SapphireSun
Is this a comment or an answer?
Roger Pate
I thought that *arrPtr had the same value in both usages. In the second, the subscript [] requires the first operand to be a pointer to an object type. I thought the "address of the array" met that requirement.
ed mach
A: 

In C, arrays are pretty much just a convenience thing. All an “array” variable is is a pointer to the start of a block of data; just as an int [] equates to an int*, i.e. the location in memory of an int, an int [][] is a double pointer, an int**, which points to the location in memory of... another pointer, which in turn points to an actual particular int.

Noah Witherspoon
No, this is wrong. As *function parameters* `int[]` and `int*` are equivalent (notice not even a `const` that some people expect), but not true for `int[][]` and `int**` and any other use of arrays other than function parameters.
Roger Pate
The only difference I know of between these forms applies when the variables are initially declared. When accessing an array, pointer notation (`*(a+i*sizeof(int))`, where `a` was declared as an array of ints) is equivalent to `a[i]`, is it not?
Noah Witherspoon
Roger Pate
The function parameter special case is confusing, because there (and only there) `int[]` and `int*` are identical (even if a size is specified for the array type), but it doesn't apply to multidimensional arrays (only the leftmost/innermost array size can be omitted, so `T[][10]` is the same as `T(*)[10]`, which is really `U[]` to `U*` with U being `T[10]`) and doesn't apply to any other use of arrays.
Roger Pate