linux-c-programming.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Something interesting with multi-subscript arrays.
@ 2004-05-26 15:30 David Chao
  2004-05-26 20:00 ` Glynn Clements
  0 siblings, 1 reply; 2+ messages in thread
From: David Chao @ 2004-05-26 15:30 UTC (permalink / raw)
  To: linux-c-programming

Hi,

I happen to learn something interesting abt multiple-subscript arrays at
work today. I am hoping if someone can confirm what I discovered. Having
done a fair amt of C programming, I always thought that arrays like:

unsigned char a[2][3];

can be accessed using like that:

unsigned char **b;

b=a;

Then using *(*(b+1)+1) (for eg.) to access the array. Since, isn't this
equivalent to a[1][1]?

However, I am totally wrong! b=a generates a surprise compiler error. I
spent quite sometime to resolve this error. To cut a long story short, I
found another interesting fact. This code:

#include <stdio.h>

int main(void)
{
    unsigned char a[2][3] = {{'a','b','c'},
                             {'d','e','f'}};
    unsigned char (*b)[3];

    b = a;

    printf("%d\n", b);
    printf("%d\n", *b);
    printf("%d\n", **b);
    printf("%c\n", **b);
    system("PAUSE");
    return 0;
}

gives the result:

2293592
2293592
97
a
Press any key to continue . . .

This means that *b does nothing at all in this case. Surprise! Learn
something new everyday.

Best,
David


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Something interesting with multi-subscript arrays.
  2004-05-26 15:30 Something interesting with multi-subscript arrays David Chao
@ 2004-05-26 20:00 ` Glynn Clements
  0 siblings, 0 replies; 2+ messages in thread
From: Glynn Clements @ 2004-05-26 20:00 UTC (permalink / raw)
  To: David Chao; +Cc: linux-c-programming


David Chao wrote:

> I happen to learn something interesting abt multiple-subscript arrays at
> work today. I am hoping if someone can confirm what I discovered. Having
> done a fair amt of C programming, I always thought that arrays like:
> 
> unsigned char a[2][3];
> 
> can be accessed using like that:
> 
> unsigned char **b;
> 
> b=a;

They aren't the same thing. a is an array of 2 arrays of 3 characters;
b is a pointer to (one or more) pointers to (one or more) characters.

Arrays are passed by reference, so when "a" is used as an expression,
it is a pointer to (one or more) arrays of characters.

Both can be accessed using the same notation, i.e. a[i][j] and
b[i][j], but they aren't the same thing.

> Then using *(*(b+1)+1) (for eg.) to access the array. Since, isn't this
> equivalent to a[1][1]?

No. a[i] is an array of 3 characters, while b[i] is a pointer to (one
or more) characters. E.g. sizeof(a[i]) is 3, while sizeof(b[i]) will
typically be either 4 or 8 (depending upon whether pointers are 32 or
64 bits).

The following would work:

	unsigned char (*b)[3] = a;

So would:

	unsigned char *b[2];
	b[0] = a[0];
	b[1] = a[1];

So would:

	unsigned char **b = malloc(2 * sizeof(char *));
	b[0] = a[0];
	b[1] = a[1];

In all cases, a[i][j] and b[i][j] would refer to the same memory
locations.

> However, I am totally wrong! b=a generates a surprise compiler error.

Yep. Pointer type mismatch. In this context, a has type "pointer to
array(s) of 3 characters" while b has type "pointer to pointer(s) to
character(s)".

> I
> spent quite sometime to resolve this error. To cut a long story short, I
> found another interesting fact. This code:
> 
> #include <stdio.h>
> 
> int main(void)
> {
>     unsigned char a[2][3] = {{'a','b','c'},
>                              {'d','e','f'}};
>     unsigned char (*b)[3];

That's OK.

>     b = a;
> 
>     printf("%d\n", b);
>     printf("%d\n", *b);
>     printf("%d\n", **b);
>     printf("%c\n", **b);
>     system("PAUSE");
>     return 0;
> }
> 
> gives the result:
> 
> 2293592
> 2293592
> 97
> a
> Press any key to continue . . .
> 
> This means that *b does nothing at all in this case.

In this case, "b" is an alias for "&a[0]" (or just "a"), while "*b" is
an alias for "&a[0][0]". IOW, "b" points to the first array, while
"*b" points to the first element of the first array. Both of these are
at the same place in memory (the address of the first element of an
array is, obviously, equal to the address of the array itself), but
the first is larger (sizeof(*b) is 3, sizeof(**b) is 1).

> Surprise!

Not to anybody who actually understands pointers and arrays.

> Learn something new everyday.

If this is new to you, I suggest getting hold of a copy of:

	The C Programming Language (Second Edition)
	Brian W Kernighan & Dennis M Ritchie
	Prentice Hall

and reading chapter 5 (entitled "Pointers and Arrays").

-- 
Glynn Clements <glynn.clements@virgin.net>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-05-26 20:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-05-26 15:30 Something interesting with multi-subscript arrays David Chao
2004-05-26 20:00 ` Glynn Clements

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).