By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,293 Members | 1,397 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,293 IT Pros & Developers. It's quick & easy.

Question about pointers and multi-dimension arrays

P: n/a
Hello everyone, merry christmas!

I have some questions about the following program:

arrtest.c
------------

#include <stdio.h>

int main(int agc, char *argv[]) {
int array2d[2][2] = { {1,2} , {3,4} };
int (* arrp)[2] = array2d;

printf("&array2d = %p\tarray2d = %p\t*array2d = %p\n", &array2d,
array2d, *array2d);
printf("&arrp = %p\tarp = %p\t*arrp = %p\t**arp = %d\n", &arrp,
arrp, *arrp, **arrp);

return 0;
}

When I compile and run the program I get the following results:

&array2d = 0xbfd9e880 array2d = 0xbfd9e880 *array2d = 0xbfd9e880
&arrp = 0xbfd9e890 arrp = 0xbfd9e880 *arrp =
0xbfd9e880 **arrp = 1

My questions are:

Why is the address of array2d (&array2d), the value (array2d) and the
contents of that value (*array2d) all the same ? (0xbfd9e880)

array2d contains the value: 0xbfd9e880. When dereferenced (*array2d)
it gives the same value, 0xbfd9e880
But when the same address is dereferenced again (**array2d) it gives
an integer (1) and not an address like above.

How does the compiler "understands" if it should return a pointer or
the value stored in that address?

How does the compiler stores array variables so that &array == array ?

Thanks for your time, I hope you will understand my questions
Dec 27 '07 #1
Share this Question
Share on Google+
17 Replies


P: n/a
DiAvOl said:

<snip>
int array2d[2][2] = { {1,2} , {3,4} };
<snip>
Why is the address of array2d (&array2d), the value (array2d) and the
contents of that value (*array2d) all the same ?
They aren't the same, because they have different types. &array2d has type
int (*)[2][2], array2d has type int[2][2] (which is converted into a value
of type int(*)[2] when used in value contexts), and *array2d has type
int[2] (which is converted into a value of type int * when used in value
contexts).

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Dec 27 '07 #2

P: n/a

"DiAvOl" <ch******@yahoo.comwrote in message news:06ce14cb-
int main(int agc, char *argv[]) {
int array2d[2][2] = { {1,2} , {3,4} };
int (* arrp)[2] = array2d;

printf("&array2d = %p\tarray2d = %p\t*array2d = %p\n", &array2d,
array2d, *array2d);
printf("&arrp = %p\tarp = %p\t*arrp = %p\t**arp = %d\n", &arrp,
arrp, *arrp, **arrp);

return 0;
}
The important thing to know about multidimensional arrays in C 89 is that
they are effectively broken. Whilst they can be declared and used, the
syntax needed to do anything much with them, like pass them to other
functions, is too complicated. They also cannot be resized at runtime.

So just forget about them until you are familiar with most of the rest of
the language. Any multi-dimensional array can easily be emulated with a
single dimension.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Dec 27 '07 #3

P: n/a
0xbfd9e880 <=== Memory address
------------
| 1 | <=== Contents
------------

My point is, how can the address 0xbfd9e880 hold both an address and a
number ?

When array2d is dereferenced (*array2d) it should return the contents
of it's value (contents of memory location 0xbfd9e880) but it returns
the same address.

When array2d is double dereferenced (**array2d) it's the same as
*(*array2d), *array2d as we saw before is the address 0xbfd9e880 so
when it is dereferenced this time, it returns an integer.

How can the compiler determine when to return an integer and when to
return the address?

Thanks for your fast reply
Dec 27 '07 #4

P: n/a
Malcolm McLean said:

<snip>
The important thing to know about multidimensional arrays in C 89 is that
they are effectively broken.
I disagree. They work just fine if you treat them right.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Dec 27 '07 #5

P: n/a
DiAvOl said:
0xbfd9e880 <=== Memory address
------------
| 1 | <=== Contents
------------

My point is, how can the address 0xbfd9e880 hold both an address and a
number ?
Please switch, if necessary, to a non-proportional font such as Courier. It
will make the following diagram clearer.

| M |
| a +-----+-----+-----+-----+---
| i | 1 | 3 | 5 | 7 |
| n X-----+-----+-----+-----+--
| High Street
| R +-----+-----+-----+-----+---
| o | 2 | 4 | 6 | 8 |
| a +-----+-----+-----+-----+-
| d |

See the X? It represents a single point on the Earth's surface. We can
think of this point as "1 High Street" if we like - so in that sense it
can be thought of as an address. On the other hand, it's also the corner
of a living room. On the other other hand, it's also a brick. On the other
other other hand, it's also a Carbon atom. The question "what will we find
at X?" depends on the level at which we're asking the question.

When array2d is dereferenced (*array2d) it should return the contents
of it's value (contents of memory location 0xbfd9e880) but it returns
the same address.
Crank up the magnification on your binoculars, and what you see at X will
change - but it's still at the same place, isn't it?

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Dec 27 '07 #6

P: n/a
I perfectly understand what you are saying. I'll try to describe my
question better.

Suppose I am the C compiler and I see the following constructs:

1) printf("%d", *p); // p is an int pointer

I should fetch the address which p contains and find an int value
there.

All fine with this one

2)
Having:

int array2d[2][2] = { {1,2} , {3,4} };

&array2d = 0xbfd9e880 array2d = 0xbfd9e880 *array2d = 0xbfd9e880

I (the compiler) see the construct: printf("%p", *array2d); .

I should fetch the address which array2d contains (0xbfd9e880) and
find an int pointer there. This returns 0xbfd9e880, so the address
0xbfd9e880 contains the int pointer 0xbfd9e880.

Then I see the construct: printf("%d", **array2d);

I should fetch the address which *array2d contains (0xbfd9e880 as we
saw above) and find an int value there

But I saw before that 0xbfd9e880 contains the int pointer 0xbfd9e880
not an int number... I am confused

Thanks very much for your time and example and sorry for my bad
english.



Dec 27 '07 #7

P: n/a

"DiAvOl" <ch******@yahoo.comwrote in message
news:06**********************************@c49g2000 hsc.googlegroups.com...
Hello everyone, merry christmas!

I have some questions about the following program:

arrtest.c
------------

#include <stdio.h>

int main(int agc, char *argv[]) {
int array2d[2][2] = { {1,2} , {3,4} };
int (* arrp)[2] = array2d;

printf("&array2d = %p\tarray2d = %p\t*array2d = %p\n", &array2d,
array2d, *array2d);
printf("&arrp = %p\tarp = %p\t*arrp = %p\t**arp = %d\n", &arrp,
arrp, *arrp, **arrp);

return 0;
}

When I compile and run the program I get the following results:

&array2d = 0xbfd9e880 array2d = 0xbfd9e880 *array2d = 0xbfd9e880
&arrp = 0xbfd9e890 arrp = 0xbfd9e880 *arrp =
0xbfd9e880 **arrp = 1

My questions are:

Why is the address of array2d (&array2d), the value (array2d) and the
contents of that value (*array2d) all the same ? (0xbfd9e880)
Here is what I can think of (subject to correction of the experts..)

the typeof(array2d) = "pointer to an array of 2 ints". But array2d is an
r-value , not an l-value. This may be the reason why
&array2d evaluates to the same address even though the typeof(&array2d) ==
"pointer to a pointer to array of 2 ints".
Finally *array2d has the type "array of 2 ints". But in C array is not first
class type and *array2d is not a "lvalue". Thus *array2d evaluates
to the same as array2d.
A case where the expressions have different types , but same values..!
>
array2d contains the value: 0xbfd9e880. When dereferenced (*array2d)
array2d does not "contain" the value 0xbfd9e880 but rather evaluates to that
value but having the type "pointer to an array of 2 ints".
it gives the same value, 0xbfd9e880
But when the same address is dereferenced again (**array2d) it gives
an integer (1) and not an address like above.
I am not sure how the compiler understands **array2d. Perhaps someone could
help here..
>
How does the compiler "understands" if it should return a pointer or
the value stored in that address?

How does the compiler stores array variables so that &array == array ?

Thanks for your time, I hope you will understand my questions
You have to read the C FAQ by Steve Summit on Arrays and Pointers for
clarity on "pointers to arrays". I dont have the link handy though..
Dec 27 '07 #8

P: n/a
DiAvOl wrote:
I perfectly understand what you are saying. I'll try to describe my
question better.
You should quote relevant parts of the post you're replying to, to make
context clear.
Suppose I am the C compiler and I see the following constructs:

1) printf("%d", *p); // p is an int pointer

I should fetch the address which p contains and find an int value
there.

All fine with this one
Right.
2)
Having:

int array2d[2][2] = { {1,2} , {3,4} };

&array2d = 0xbfd9e880 array2d = 0xbfd9e880 *array2d = 0xbfd9e880

I (the compiler) see the construct: printf("%p", *array2d); .

I should fetch the address which array2d contains (0xbfd9e880) and
find an int pointer there. This returns 0xbfd9e880, so the address
0xbfd9e880 contains the int pointer 0xbfd9e880.

Then I see the construct: printf("%d", **array2d);

I should fetch the address which *array2d contains (0xbfd9e880 as we
saw above) and find an int value there

But I saw before that 0xbfd9e880 contains the int pointer 0xbfd9e880
not an int number... I am confused
A pointer corresponds both to an address and a type. The type determines
how much stuff the address refers to, and how to interpret it.
Supposing an int is four bytes:
+-----------+
|00 00 00 01| 0xbfd9e880
+-----------+
|00 00 00 02| 0xbfd9e884
+-----------+
|00 00 00 03| 0xbfd9e888
+-----------+
|00 00 00 04| 0xbfd9e88c
+-----------+

Now the object declared `int array2d[2][2] = { {1,2} , {3,4} };` is an
array of arrays of ints, and spans 16 bytes. Thus, &array2d has type
"pointer to array of two arrays of two ints", and value 0xbfd9e880. Now,
an array, when is not used as the operand of & (or sizeof, or, in the case
of a string literal, as the initializer of an array of char), evaluates to
a pointer to its first element. Now, the first element of array2d is still
an array, but this time it is an array of ints.
So, array2d evaluates to &array2d[0], which is a pointer equal to &array2d,
except for its type: the former is a pointer to array of arrays of ints,
whereas the latter is a pointer to array of ints.
Now, *array2d what &array2d[0] points to, that is an array of two ints
starting at 0xbfd9e880. Since it is itself an array, it evaluates to a
pointer to its first element. This pointer still has value 0xbfd9e880, but
its type is pointer to int. Dereference it another time and you get the
int contained at that location, i.e. 1.

Resuming: &array2d, array2d, and *array2d all are (or evaluate to)
pointers to objects starting at that address. But the first points to the
whole 2d array (16 bytes), the second points to its first row (8 bytes),
and the third points to its first element (4 bytes, the int 1).
I hope I've been clear.

Nitpick: printf expects "%p" to correspond a pointer to void, that is a
pointer with no type information. You can convert a pointer of another
type to a pointer to void with a cast:
printf("%p\n", (void *)&array2d);
On most modern machines this makes no difference, as all pointers are the
same size. But on older machines pointers to void are larger, so on those
printf("%p\n", &array2d);
tries to read more data it was passed to. According to the C standard, the
latter has undefined behavior, that is the standard allows a program with
it to behave whatever the implementation likes most. Even if nowadays that
is almost always the same thing as the former, the cost of adding the cast
to be safe is so low that there is no reason not to do that.

--
Army1987 (Replace "NOSPAM" with "email")
Dec 27 '07 #9

P: n/a
On Dec 27, 10:54 pm, army1987 <army1...@email.itwrote:
DiAvOl wrote:
I perfectly understand what you are saying. I'll try to describe my
question better.

You should quote relevant parts of the post you're replying to, to make
context clear.
Suppose I am the C compiler and I see the following constructs:
1) printf("%d", *p); // p is an int pointer
I should fetch the address which p contains and find an int value
there.
All fine with this one
Right.
2)
Having:
int array2d[2][2] = { {1,2} , {3,4} };
&array2d = 0xbfd9e880 array2d = 0xbfd9e880 *array2d = 0xbfd9e880
I (the compiler) see the construct: printf("%p", *array2d); .
I should fetch the address which array2d contains (0xbfd9e880) and
find an int pointer there. This returns 0xbfd9e880, so the address
0xbfd9e880 contains the int pointer 0xbfd9e880.
Then I see the construct: printf("%d", **array2d);
I should fetch the address which *array2d contains (0xbfd9e880 as we
saw above) and find an int value there
But I saw before that 0xbfd9e880 contains the int pointer 0xbfd9e880
not an int number... I am confused

A pointer corresponds both to an address and a type. The type determines
how much stuff the address refers to, and how to interpret it.
Supposing an int is four bytes:
+-----------+
|00 00 00 01| 0xbfd9e880
+-----------+
|00 00 00 02| 0xbfd9e884
+-----------+
|00 00 00 03| 0xbfd9e888
+-----------+
|00 00 00 04| 0xbfd9e88c
+-----------+

Now the object declared `int array2d[2][2] = { {1,2} , {3,4} };` is an
array of arrays of ints, and spans 16 bytes. Thus, &array2d has type
"pointer to array of two arrays of two ints", and value 0xbfd9e880. Now,
an array, when is not used as the operand of & (or sizeof, or, in the case
of a string literal, as the initializer of an array of char), evaluates to
a pointer to its first element. Now, the first element of array2d is still
an array, but this time it is an array of ints.
So, array2d evaluates to &array2d[0], which is a pointer equal to &array2d,
except for its type: the former is a pointer to array of arrays of ints,
whereas the latter is a pointer to array of ints.
Now, *array2d what &array2d[0] points to, that is an array of two ints
starting at 0xbfd9e880. Since it is itself an array, it evaluates to a
pointer to its first element. This pointer still has value 0xbfd9e880, but
its type is pointer to int. Dereference it another time and you get the
int contained at that location, i.e. 1.

Resuming: &array2d, array2d, and *array2d all are (or evaluate to)
pointers to objects starting at that address. But the first points to the
whole 2d array (16 bytes), the second points to its first row (8 bytes),
and the third points to its first element (4 bytes, the int 1).
I hope I've been clear.

Nitpick: printf expects "%p" to correspond a pointer to void, that is a
pointer with no type information. You can convert a pointer of another
type to a pointer to void with a cast:
printf("%p\n", (void *)&array2d);
On most modern machines this makes no difference, as all pointers are the
same size. But on older machines pointers to void are larger, so on those
printf("%p\n", &array2d);
tries to read more data it was passed to. According to the C standard, the
latter has undefined behavior, that is the standard allows a program with
it to behave whatever the implementation likes most. Even if nowadays that
is almost always the same thing as the former, the cost of adding the cast
to be safe is so low that there is no reason not to do that.

--
Army1987 (Replace "NOSPAM" with "email")
Hi ,

I just want to give a small clue to make you understand your problem.

Since, array2d is an double dimension array, If you want to access
array2d you need to deference it double time.
If you deference it once you will get the address.

Its just a clue for you. I hope you can easily analyse the problem.

bye
MMK
Dec 27 '07 #10

P: n/a
DiAvOl <ch******@yahoo.comwrites:
I perfectly understand what you are saying. I'll try to describe my
question better.
<snip>
2)
Having:

int array2d[2][2] = { {1,2} , {3,4} };

&array2d = 0xbfd9e880 array2d = 0xbfd9e880 *array2d = 0xbfd9e880

I (the compiler) see the construct: printf("%p", *array2d); .

I should fetch the address which array2d contains (0xbfd9e880) and
find an int pointer there.
No. array2d is an array of two arrays (type int [2][2]). When used
in most contexts it is converted to a pointer to it's first element
(type int(*)[2]). But note, this "first element" is an array so
*array2d denotes an array, not a single int (the type is int [2]).
How is this expression treated when it is passed to printf? Like any
other array-valued expression, it is converted to a pointer to its
first element. Of course, numerically, this looks the same as
array2d, but you could see the difference if you printed the size as
well:

printf("Pointer: %p, size: %zu\n", (void *)array2d, sizeof array2d);
printf("Pointer: %p, size: %zu\n", (void *)*array2d, sizeof *array2d);

[If %zu does not work for you -- it is C99 -- replace with %lu and
cast the sizeof expressions to (unsigned long). I have cast the
pointers to (void *) because that is what %p requires -- it does not
have any impact on the argument above.]

sizeof is one of the special places where the conversion from array to
pointer does *not* happen, so sizeof *array2d is the size of the
(sub-)array and not just the size of a pointer on your system.

--
Ben.
Dec 27 '07 #11

P: n/a
so if I'm not mistaken *array2d does NOT fetch (dereference) any
value, it just changes the type of the pointer. Only **array2d really
fetches the value. Is this correct?

Thanks
Dec 27 '07 #12

P: n/a
DiAvOl <ch******@yahoo.comwrites:

In the context of:

int array2d[2][2];

[Snipping is good, but pleas keep enough context for each message to
stand alone if need be.]
so if I'm not mistaken *array2d does NOT fetch (dereference) any
value, it just changes the type of the pointer. Only **array2d really
fetches the value. Is this correct?
Not quite. The trouble is that "fetch" is not the same as
"dereference". array2d (in most expressions) is converted to a
pointer to an array. The * in *array2d removes the "pointer" part.
I.e. it does do a dereference, but nothing is fetched from anywhere.

It helps to think at the level of the so-called C "abstract machine".
This is not the level of machine addresses and load and stores, but
the level of values and types. At this level, a * always turns a
pointer into the thing to which it points, but if that thing is an
array which needs to be turned into a pointer right away you will not
see any "fetching" associated with the *.

--
Ben.
Dec 27 '07 #13

P: n/a
On Thu, 27 Dec 2007 17:56:43 +0530, "Ravishankar S"
<ra***********@in.bosch.comwrote:
>
"DiAvOl" <ch******@yahoo.comwrote in message
news:06**********************************@c49g200 0hsc.googlegroups.com...
>Hello everyone, merry christmas!

I have some questions about the following program:

arrtest.c
------------

#include <stdio.h>

int main(int agc, char *argv[]) {
int array2d[2][2] = { {1,2} , {3,4} };
int (* arrp)[2] = array2d;

printf("&array2d = %p\tarray2d = %p\t*array2d = %p\n", &array2d,
array2d, *array2d);
printf("&arrp = %p\tarp = %p\t*arrp = %p\t**arp = %d\n", &arrp,
arrp, *arrp, **arrp);

return 0;
}

When I compile and run the program I get the following results:

&array2d = 0xbfd9e880 array2d = 0xbfd9e880 *array2d = 0xbfd9e880
&arrp = 0xbfd9e890 arrp = 0xbfd9e880 *arrp =
0xbfd9e880 **arrp = 1

My questions are:

Why is the address of array2d (&array2d), the value (array2d) and the
contents of that value (*array2d) all the same ? (0xbfd9e880)

Here is what I can think of (subject to correction of the experts..)

the typeof(array2d) = "pointer to an array of 2 ints". But array2d is an
The type of array2d is array of 2 arrays of 2 int. In syntax form, it
is exactly as in the original post, int [2][2]
>r-value , not an l-value. This may be the reason why
&array2d evaluates to the same address even though the typeof(&array2d) ==
"pointer to a pointer to array of 2 ints".
The type of &array2d is pointer to array of 2 array of 2 int. In
syntax form, int(*)[2][2].
>Finally *array2d has the type "array of 2 ints". But in C array is not first
class type and *array2d is not a "lvalue". Thus *array2d evaluates
to the same as array2d.
No they don't. While they do evaluate to the same address, each has a
distinct type (as you note below). In situations other than the three
exceptions which don't apply here, an expression of array type is
converted to a pointer to the first element of the array with type
pointer to element type. Therefore:

*array2d (which is by definition exactly the same as
array2d[0]) evaluates to &array2d[0][0] with type pointer to int
(int*).

array2d evaluates to &array2d[0] with type pointer to array of
2 int (int(*)[2]).
>A case where the expressions have different types , but same values..!
Only in the conceptual sense similar to a double of 1.0 and an int of
1 having the same value.
>
>>
array2d contains the value: 0xbfd9e880. When dereferenced (*array2d)
array2d does not "contain" the value 0xbfd9e880 but rather evaluates to that
value but having the type "pointer to an array of 2 ints".
Pointer to array of 2 array of 2 int.
>

>it gives the same value, 0xbfd9e880
But when the same address is dereferenced again (**array2d) it gives
an integer (1) and not an address like above.
I am not sure how the compiler understands **array2d. Perhaps someone could
help here..
**array2d is by definition exactly the same as array2d[0][0].
>
>>
How does the compiler "understands" if it should return a pointer or
the value stored in that address?

How does the compiler stores array variables so that &array == array ?

Thanks for your time, I hope you will understand my questions

You have to read the C FAQ by Steve Summit on Arrays and Pointers for
clarity on "pointers to arrays". I dont have the link handy though..
www.c-faq.com
Remove del for email
Dec 31 '07 #14

P: n/a
On Thu, 27 Dec 2007 17:56:43 +0530, "Ravishankar S"
<ra***********@in.bosch.comwrote:
>
"DiAvOl" <ch******@yahoo.comwrote in message
news:06**********************************@c49g2000 hsc.googlegroups.com...
<snip: Q about 2-dim array>
You have to read the C FAQ by Steve Summit on Arrays and Pointers for
clarity on "pointers to arrays". I dont have the link handy though..
I wouldn't say you absolutely _must_ but it does often help.

Web at http://c-faq.com or the usual places for (big8) FAQs:
news:comp.answers,$group ftp://rtfm.mit.edu http://faqs.org

Chris Torek's http://web.torek.net/c is also good for the particular
topics it covers, which are fewer but does include this one.

- formerly david.thompson1 || achar(64) || worldnet.att.net
Jan 7 '08 #15

P: n/a
David Thompson <da************@verizon.netwrites:
[...]
Web at http://c-faq.com or the usual places for (big8) FAQs:
news:comp.answers,$group ftp://rtfm.mit.edu http://faqs.org
I find faqs.org to be much more difficult to navigate than c-faq.com.
Chris Torek's http://web.torek.net/c is also good for the particular
topics it covers, which are fewer but does include this one.
I'm sure it would be excellent if it actually existed.

Try <http://www.torek.net/torek/c/>.

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
[...]
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jan 7 '08 #16

P: n/a
"David Thompson" <da************@verizon.netwrote in message
news:bu********************************@4ax.com...
On Thu, 27 Dec 2007 17:56:43 +0530, "Ravishankar S"
<ra***********@in.bosch.comwrote:

"DiAvOl" <ch******@yahoo.comwrote in message
news:06**********************************@c49g2000 hsc.googlegroups.com...
<snip: Q about 2-dim array>
You have to read the C FAQ by Steve Summit on Arrays and Pointers for
clarity on "pointers to arrays". I dont have the link handy though..
I wouldn't say you absolutely _must_ but it does often help.
I'd say it helps a lot, especially the printed version. For me it put the
array pointer relation in the right prespective
>
Web at http://c-faq.com or the usual places for (big8) FAQs:
news:comp.answers,$group ftp://rtfm.mit.edu http://faqs.org

Chris Torek's http://web.torek.net/c is also good for the particular
topics it covers, which are fewer but does include this one.

- formerly david.thompson1 || achar(64) || worldnet.att.net

Jan 7 '08 #17

P: n/a
On Dec 27 2007, 2:51 am, DiAvOl <charp...@yahoo.comwrote:
Hello everyone, merry christmas!
[snip]
How does the compiler stores array variables so that &array == array ?
It's not about how the array variables are stored, but about how
they're treated in various contexts.

In most contexts, when the compiler sees an array identifier or an
expression that evaluates to an array, it implicitly converts the type
of the identifier or expression from "array of T" to "pointer to T",
and converts the value to a pointer to the first element of the array.

So, given the following:

int arr1[N];

wherever the compiler sees "arr1" in the code, it will convert the
type of arr from "N-element array of int" to "pointer to int", and
will set the value to be a pointer to the first element of arr (for
illustration's sake, call it 0x8000).

The exceptions to this rule are when arr1 is an operand of either the
address-of (&) operator or the sizeof operator; instead of returning a
pointer to the first element of the array, the & operator returns a
pointer to the whole array. However, given how C arrays work, these
two things (the pointer to the first element of the array and the
pointer to the array) turn out to be the same *value*. IOW, the
address of "arr1" is the same as the address of "arr1[0]"; the value
is just interpreted differently. So, assuming that the base address
of our array is 0x8000:

&arr == arr

in terms of the *value* of the pointer. However, the *types* are not
equivalent:

typeof &arr1 == int (*)[N] // pointer to N-element array of int
typeof arr1 == int *

Since this is a 1-d array,

typeof *arr1 == int

Bumping this up to multiple dimensions, assume we have the following:

int arr2[N][M];

Again, &arr2 evaluates to a pointer to the whole array and arr2
evaluates to a pointer to the first element of the array. But now,
the type of arr2[0] is no longer an int, but an M-element array of
int. Since the expression *arr2 evaluates to an array type, the same
rules that applied to the identifier arr1 apply to the expression
*arr2; namely, the type of *arr2 is converted from "M-element array of
int" to "pointer to int", and the value of the expression is set to
point to the first element of the array (&arr2[0][0]). Again, the
address of arr2 is the same as the address of arr2[0] which is the
same as the address of arr2[0][0]. It's the types of each expression
that change:

typeof &arr2 == int (*)[N][M]
typeof arr2 == int (*)[M]
typeof *arr2 == int *

Hope that helps (and was minimally correct).
Jan 7 '08 #18

This discussion thread is closed

Replies have been disabled for this discussion.