[Courses] Re: pointers, array's, and sizeof()

Julie jockgrrl at austin.rr.com
Sun Feb 3 15:40:40 EST 2002


coldfire wrote:
> 
> > wrong wrong.
> > it is only in function parameters out of convenience that the compiler
> > when it sees char a[] for example, will  treat it as  if it was char a*;
> > <-- notice will be treated not converted...
> > and thats only in function parameters !!
> 
> <huge ass snip>
> 
> are we discussing purely C?  or C++?  if C++ ...
> 
>         int a[5] = {1, 2, 3, 4, '\0'};
>         cout << a << endl;
>         cout << *a << endl;
> 
> run the above code:
> 
>         # ./a.out
>         0xbffff788
>         1
> 
> ok, the formal definition of a pointer?  "a pointer stores an address in
> memory."  as indicated, 'a' is merely a pointer.  hence the pointer
> notation i used in a previous email.  *(a+0), *(a+1), *(a+2), etc. will
> print the contents of the array.

I think part of the disconnect is in dealing with l-values
and r-values.  When used as an r-value, an array is always the
address of the first element.  This is irrelevant whether the
r-value is an actual function parameter, an operand in an
expression, or an expression iteslf.  When used as an l-value,
it is an array.  When it's the parameter to sizeof(), it's
whatever it is in terms of how much actual storage is declared
to hold a one of them, or hold the entire array if the object
is itself an array.

An r-value is on the ... right hand side of an equals sign, an
l-value is on the ... left hand side.  Expressions are made
up of r-values, regardless of being conditionals, function
actual parameters, or expressions.

server-> cat -n lvalue.c
     1	main (int argc, char ** argv)
     2	{
     3		char	a[10];
     4		char	*b;
     5	
     6		b = a;
     7		a = b;
     8	}

server-> cc -c lvalue.c
lvalue.c: In function `main':
lvalue.c:7: incompatible types in assignment


This code (should hopefully) shows the difference between the two.

server-> cat array.c
char	a[] = "This is an array of char";
char	*b = "This is a pointer to char";
char	c[10] = "Ten Chars";

main (int argc, char ** argv)
{
	printf ("a = %x, sizeof a = %d\n", a, sizeof a);
	printf ("b = %x, sizeof b = %d\n", b, sizeof b);
	printf ("c = %x, sizeof c = %d\n", c, sizeof c);
}
server-> make array
cc     array.c   -o array
server-> ./array
a = 8049588, sizeof a = 25
b = 8048518, sizeof b = 4
c = 80495a8, sizeof c = 10

Neither a nor c can be used as an l-value, except in a variable
initialization, because array assignment is unsupported in
standard C.  All three can be used as r-values.  In the case
of a and c, the value of each is &a[0] and &c[0], respectively.
In the case of b it's the value of whatever was assigned to b.

Thus the value of &a[0] and &c[0] are both fixed while the
value of &b[0] can be changed by assigning a new (char *) to b.
Adding this code to array.c

	printf ("&a[0] = %x\n", &a[0]);
	printf ("&b[0] = %x\n", &b[0]);
	b = "Another string";
	printf ("&b[0] = %x\n", &b[0]);

produces this additional output

&a[0] = 8049600
&b[0] = 8048568
&b[0] = 80485df

when it is re-run.  As you saw in the earlier example, trying to
code

	a = "A different string";

would result in a compilation error (unless it was the initial
declaration of "a" in other than an "auto" storage class.
-- 
Julianne Frances Haugh             Life is either a daring adventure
jockgrrl at austin.rr.com                 or nothing at all.
					    -- Helen Keller



More information about the Courses mailing list