Sign in to follow this  
law_order

Array question...i'm really confused...

Recommended Posts

law_order    122
hi people...i'm new here an i'd really appreciate your help... Please consider the following simple c program.(taken from a book) " #include <stdio.h> int multi[2][4]; main() { printf("\nmulti = %u", multi); printf("\nmulti[0] = %u", multi[0]); printf("\n&multi[0][0] = %u\n", &multi[0][0]); return(0); } OUTPUT: multi = 1328 multi[0] = 1328 &multi[0][0] = 1328 " Now...What i'm wondering,is how all three output values are the same... I underestand that "multi"is a pointer to "multi[0]".Also,multi[0] is also array,which means that multi[0] is also pointer to the first element of the 2d array.(which is multi[0][0]) Finally the statement(&multi),would also give us an output value of 1328! (of course,although all three values will be the same,the actual value can vary..) As we also know,pointers are nothing more than variables that like all variables have to reside somewhere in memory... In the previous code example,the output values,imply that both pointers + the first element multi[o][o] reside in the same memory address... How is that possible???i can't really inderestand it... What i also know,is that arrays have a fixed size... So how is it possble that two pointers and an integer value have the same starting address??? I'm really confused...I'd really appreciate any answers... Thanks a lot.

Share this post


Link to post
Share on other sites
jerm007    198
Hey!

It's actually not 2 pointers, it is just one. The compiler takes care of the 2 dimensional addressing for you behind the scenes. That's why you get the same number always, as you are just accessing the first element in the array. You can emulate a 2 dimensional array with only a single-d array like this:

char ar[20];

int width = 5;
int height = 4;

int x=2, y=1;

char val = ar[width * y + x];

This will effectively emulate the following:
char ar[4][5];
char val=ar[1][2];

Hope that helps!

Jeremiah

Share this post


Link to post
Share on other sites
law_order    122
Hi jeremaiah!
thanks a lot for your answer.

so...i underestood why there's only one pointer...

but i still have a question...

let's take an even simpler example

int ar[3];

the satements &ar and &ar[0] will give me the same value...

so i still wonder,how can both,the pointer and the first elemt,have the same starting adress...

thanks again.

Share this post


Link to post
Share on other sites
TheBluMage    372
I haven't done a lot of C/C++ programming, but I think I know enough to take a stab at it. When you declare an array with a constant length like this:

int myArray[4];
//or
int myArray[] = {8, 9, 10, 11};

When an array is declared as above, myArray isn't actually a pointer. Since the size of the array is known at compile time, it is accessed by value, thus making it possible to allocate it on the stack as well as the heap. It's kind of like a mini-struct without members that just has length information. Go ahead and print the result of sizeof(myArray) and you'll find that that the length of the array is returned, not the size of a pointer to an array. If I'm wrong, someone please correct me. If not, I hope this helps.

Share this post


Link to post
Share on other sites
law_order    122
Thanks a lot Theblumage..

I think i underestand what you mean...

actually,what i tend to believe,is that the name of an array isn't a "real" pointer.It's just that the compiler "treats" it as pointer..

well,i don't know...it's a little bit confusing,isn't it?

Anyway...Thanks A LOT for your replies!

Share this post


Link to post
Share on other sites
Oluseyi    2116
Where to begin?

Arrays are a falsehood in C and C++. They don't actually exist. The subscript operator ([]) performs a pointer advance and dereference. ie,
p[n];
is equivalent to
*(p + n);
"Arrays" in C and C++ have no notion of their own dimensions or bounds, so that subscript operation can extend into memory owned by a different object, thread or process, which is an access violation in most cases.

As to why you get the same value for all three printf statements, there are subtle differences.
printf("\nmulti = %u", multi);
This is a reference to the base pointer, the starting address of the multi-dimensional array, the address of the first element in the sequence.
printf("\nmulti[0] = %u", multi[0]);
This is the exact same pointer. "But there's a dereference in there, via the subscript operator. Shouldn't that yield a value result?!" Because it's a two-dimensional array, that value retrieved from the first dimension dereference is also a pointer, and because the offset for the first dimension is zero... you get the same pointer.
printf("\n&multi[0][0] = %u", &multi[0][0]);
"Okay, so what about this one? Explain that, Mr. Smartypants!" This one's disingenious, because the author sort of cheated by using the address-of operator, &, to tinker with the result. The two subscripts perform all the dereferences, yielding a value (as opposed to a pointer), but the address-of operator takes the address of that value and returns... the same pointer, again.

Hope that helped.

Share this post


Link to post
Share on other sites
law_order    122



dear oluseyi wrote:

1)p[n] is equivalent to

*(p+n)

if our array has integers,shouldn't p[n] be equivalent to
*(p+(sizeof(int)*n) ?

2)printf("\nmulti = %u", multi);
"This is a reference to the base pointer, the starting address of the multi-dimensional array, the address of the first element in the sequence"

So...here "multi" is a distinct variable that holds the address
of the first element...right?However,why when i write "&multi",
my result is the address of the first array element?
Souldn't it be the memory location that the multi pointer resides to?




I'm really sorry if my questions are silly...I'm just trying to underestand...

Share this post


Link to post
Share on other sites
Brother Bob    10344
Quote:
Original post by law_order
dear oluseyi wrote:

1)p[n] is equivalent to

*(p+n)

if our array has integers,shouldn't p[n] be equivalent to
*(p+(sizeof(int)*n) ?

No. Increasing the value of the pointer automatically increases the actual value by n times the size of the datatype it points to. So if ptr points to an object of type T, then ptr+1 points to the "next" object of type T in memory.

Quote:

2)printf("\nmulti = %u", multi);
"This is a reference to the base pointer, the starting address of the multi-dimensional array, the address of the first element in the sequence"

So...here "multi" is a distinct variable that holds the address
of the first element...right?However,why when i write "&multi",
my result is the address of the first array element?
Souldn't it be the memory location that the multi pointer resides to?

multi is the array itself, not a pointer to the array.

Share this post


Link to post
Share on other sites
ontheheap    798
Quote:
Original post by law_order



dear oluseyi wrote:

1)p[n] is equivalent to

*(p+n)

if our array has integers,shouldn't p[n] be equivalent to
*(p+(sizeof(int)*n) ?

2)printf("\nmulti = %u", multi);
"This is a reference to the base pointer, the starting address of the multi-dimensional array, the address of the first element in the sequence"

So...here "multi" is a distinct variable that holds the address
of the first element...right?However,why when i write "&multi",
my result is the address of the first array element?
Souldn't it be the memory location that the multi pointer resides to?




I'm really sorry if my questions are silly...I'm just trying to underestand...


1.
No. p[n] is the same as *(p+n); No need to use sizeof, since the compiler is smart enough to understand what you mean.
2.
No. as oluseyi pointed out, arrays are a falsehood in c/c++.
multi[n] really means *(multi+n); To get to the value pointed to by a pointer you use the dereference operator (which is the *). So the statement *(multi+n) (assuming it is an int) says you want to dereference (ie, get the value pointed to by) n*sizeof(int) bytes from the pointer multi.

hope this helps

Edit: grrrr beat by Brother Bob!

Share this post


Link to post
Share on other sites
law_order    122
thanks guys...sorry but i'm still confused...

The answer to the first question was very clear...

However,i still can't grasp that...

if multi is a pointer,what should the statement &multi give me???

i can't really underestand what dear Brother bob means by that phrase "multi is the array itself, not a pointer to the array."

Share this post


Link to post
Share on other sites
ontheheap    798
&multi is the address that multi is stored at. multi is a pointer to a block of memory (ie, your array). However, they are both the same location in memory.

[Edited by - ontheheap on October 17, 2004 8:38:41 AM]

Share this post


Link to post
Share on other sites
law_order    122
Quote:
Original post by ontheheap
&multi is the address that multi is stored at. multi is a pointer to a block of memory (ie, your array).


EXACTLY!So,why when i'm typing &multi i'm taking the adress of the first array element?

for example here:

" """ #include <stdio.h>





main() { int a[3]; printf("%d", &a); printf("%d", &a[0]); } """"


both printf(s) output the same value...

Share this post


Link to post
Share on other sites
Brother Bob    10344
No, multi is NOT a pointer to the array, it IS the array.

For a second, forget about arrays and let's think about a single variable, a single int for example.

int foo;

foo is not a pointer to the integer value, it is the integer itself. Saying foo in the code gives you the value of foo, and &foo gives you the address of to the value.

Now just think about arrays as several values grouped together instead of just a single value.

int foo[5];

foo still isn't a pointer, it is the name for the array itself. Instead of the name representing a single integer (as above), it now represents five integers. Just like in the above example, &foo gives you the address of what it represents, which is the array. The address of the array is the same as the address of the first element in the array.

Share this post


Link to post
Share on other sites
Brother Bob    10344
So why is the pointer in law_order's example located at exactly the same address as the array it points to? That would mean the pointer and the beginning of the array shares address, which makes no sense, and changing the value of the first element would also change the value of the pointer, making the pointer point somewhere else, making the array useless.

However, the name of the array can be implicitly converted to a pointer of the type of object the array contains. But this doesn't mean the name of the array actually IS a pointer, just that you can get the pointer from it.

edid: Ehm, did you delete your post?

Share this post


Link to post
Share on other sites
law_order    122
Thank you Brother bo....i finally underestood your points...

but one last question please...

we say that ar[n] is equivalent to *(ar+n).What we actually do here,is incrementing a pointer..right?
why here ar is a pointer?(if it is of course...)

thanks so much...again...

Share this post


Link to post
Share on other sites
law_order    122
Quote:
Original post by Brother Bob
So why is the pointer in law_order's example located at exactly the same address as the array it points to? That would mean the pointer and the beginning of the array shares address, which makes no sense, and changing the value of the first element would also change the value of the pointer, making the pointer point somewhere else, making the array useless.

However, the name of the array can be implicitly converted to a pointer of the type of object the array contains. But this doesn't mean the name of the array actually IS a pointer, just that you can get the pointer from it.



that makes sense...although a little bit confusing...isn't it?
so...you mean that the array's name isn't a real pointer,but sometimes the compiler treats it as a pointer?

Share this post


Link to post
Share on other sites
Brother Bob    10344
Quote:
Original post by law_order
that makes sense...although a little bit confusing...isn't it?
so...you mean that the array's name isn't a real pointer,but sometimes the compiler treats it as a pointer?

Sort of. Consider this example.

int foo[5];
int *bar = foo;

foo is not a pointer, as described above, but bar is. When you assign bar the value of foo, the compiler implicitly convert the name of the array to a pointer, and this (temporary if you like) pointer is used for to assign bar a new value.

Quote:
Original post by law_order
we say that ar[n] is equivalent to *(ar+n).What we actually do here,is incrementing a pointer..right?
why here ar is a pointer?(if it is of course...)

Yes, you increment the value of the pointer and dereference it. Whether ar is a pointer or an array doesn't really matter, since you can get the pointer from the array name.

Share this post


Link to post
Share on other sites
law_order    122
""""Original post by law_order
we say that ar[n] is equivalent to *(ar+n).What we actually do here,is incrementing a pointer..right?
why here ar is a pointer?(if it is of course...)



Yes, you increment the value of the pointer and dereference it. Whether ar is a pointer or an array doesn't really matter, since you can get the pointer from the array name."""""""

I didn't really underestand that...do you mean that again the compiler converts ar to a pointer?

Share this post


Link to post
Share on other sites
law_order    122
Quote:
Original post by Brother Bob
What, exactly, the compiler does isn't really important. But for the sake of understanding why ar[n] = *(ar + n), you can think of it like that, yes.



it seems that i'm too stupid to underestand the "real solution to the problem"...

anyway...thanks a lot...you've been extremely helpful!

Share this post


Link to post
Share on other sites
law_order    122
so sorry again brother bo...

but it would be really great,if you could expain how you can convert the arrayname to a pointer or how you can get the pointer from it....

Share this post


Link to post
Share on other sites
Brother Bob    10344
Just write name of the array, as if it already was a pointer. Like in the example above.

int foo[5];
int *bar = foo;

On the second line, foo is automatically converted to a pointer and bar is assigned the value of that pointer.

Share this post


Link to post
Share on other sites
law_order    122
Quote:
Original post by Brother Bob
Just write name of the array, as if it already was a pointer. Like in the example above.

int foo[5];
int *bar = foo;

On the second line, foo is automatically converted to a pointer and bar is assigned the value of that pointer.


thanks man...you've been great.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this