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

2D arrays and addresses

P: n/a
Hi All,

In the weekends I read a sample program from a book and think of tying
some experiments.
The code was somethng like:

#include <stdio.h>

int main()

{

char multi[3][4] =

{

{ 'A', 'B' , 'C', 'd' },
{ '1', '2' , '3', '5' },
{ 'a', 'z' , 'e' , '1' }

};

printf( " &multi[1][0] %p \n", &multi[1][0]);

printf( " multi + 1 %p \n", (multi + 1));

printf(" *(multi + 1 ) %p \n", *(multi +1));

return 0;

}

The Address for &multi[1][0] was ffbeeb2c.
In fact output of the program was same for all the printf's i.e
ffbeeb2c.
I am not able to get why

(multi + 1) and *(multi + 1 ) are showing the same output.

According to what I understood was ( multi + 1) should contain the
address and
*(multi + 1) should show the contents for that memory location.
Did I assume that ( according to output) the contents of ( multi + 1 )
is it's own address.
What is the meaning of it.

Dec 26 '06 #1
Share this Question
Share on Google+
2 Replies


P: n/a
On 25 Dec 2006 23:31:04 -0800, Co********@gmail.com wrote:
>Hi All,

In the weekends I read a sample program from a book and think of tying
some experiments.
The code was somethng like:

#include <stdio.h>

int main()

{

char multi[3][4] =

{

{ 'A', 'B' , 'C', 'd' },
{ '1', '2' , '3', '5' },
{ 'a', 'z' , 'e' , '1' }

};

printf( " &multi[1][0] %p \n", &multi[1][0]);

printf( " multi + 1 %p \n", (multi + 1));

printf(" *(multi + 1 ) %p \n", *(multi +1));

return 0;

}

The Address for &multi[1][0] was ffbeeb2c.
In fact output of the program was same for all the printf's i.e
ffbeeb2c.
I am not able to get why

(multi + 1) and *(multi + 1 ) are showing the same output.

According to what I understood was ( multi + 1) should contain the
address and
*(multi + 1) should show the contents for that memory location.
Did I assume that ( according to output) the contents of ( multi + 1 )
is it's own address.
What is the meaning of it.
1 - In most contexts (except when the operand of either the & or
sizeof operators), an expression with array type evaluates to the
address of the first element of the array with type pointer to element
type.

2 - While multi looks like a 2D array, it is actually an array of 3
arrays of 4 char. multi[0] is an array of 4 char containing 'A', 'B',
'C', and 'd'. multi[1] is an array containing '1', '2', '3', and '5'.

3 - Pointer arithmetic in c always includes an implied scaling by the
sizeof the type pointed to. If an int i occupies four bytes, then the
expression &i+1 points four bytes beyond the start of i. If a double
d occupies eight bytes, the expression &d+1 points eight bytes beyond
the start of d.

Now we apply these three "rules", recursively if necessary:

A - multi[1][0] is the element containing the '1' . It is a char. The
& operator produces the address of this element which has the type
char*. The standard requires char* and void* to have the same size
and representation. The %p expects a void* so the char* is acceptable
and you print the address of the '1'. While the char* is acceptable,
most here recommend casting the expression to void* (even if only for
consistency).

B - (multi+1) evaluates as the address of multi[0] (rule 1) plus 1.
multi[0] is an array of four char and its address is the byte that
holds the 'A' (rule 2). This address has the type pointer to array of
four char, in c notation char(*)[4]. The type pointed to is array of
four char and the sizeof this type is 4. The expression multi+1
evaluates to the address four bytes beyond the 'A' (rule 3), which is
the address of the '1'. However, adding the 1 did not change the type
which remains char(*)[4]. This is not the same type as char* and
therefore need not have the same size or representation as void*. By
applying the %p to this type, you invoke undefined behavior. You need
to cast the type to void*. Once you do this, the printf will print
the address of the '1' which is the same as A above.

C - *(multi+1) start out the same as the preceding. multi+1 is the
address of the array of four char starting with the '1'. The *
operator dereferences this address, yielding the array itself. We now
have an expression of array type. Applying rule 1 again, this
evaluates to the address of the first element ('1') with type pointer
to element type (char*). This is the same situation described in A
above.
Remove del for email
Dec 26 '06 #2

P: n/a
Co********@gmail.com writes:
In the weekends I read a sample program from a book and think of tying
some experiments.
The code was somethng like:

#include <stdio.h>
int main()
{
char multi[3][4] =
{
{ 'A', 'B' , 'C', 'd' },
{ '1', '2' , '3', '5' },
{ 'a', 'z' , 'e' , '1' }
};

printf( " &multi[1][0] %p \n", &multi[1][0]);
printf( " multi + 1 %p \n", (multi + 1));
printf(" *(multi + 1 ) %p \n", *(multi +1));
return 0;
}
[extraneous blank lines deleted; why do people feel the need to
double-space code?]

Read section 6 of the comp.lang.c FAQ, <http://www.c-faq.com>.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 26 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.