Re: [cc65] c question

From: Mark J. Reed <markjreed1mail.com>
Date: 2010-05-27 13:21:26
On Thu, May 27, 2010 at 2:32 AM, Chiron Bramberger <chiron@bramberger.com>wrote:

> But what does the * mean (on_the_right*)? I really want to truly understand
> this and not just how to "make it go". I want to get it.


It means the same thing, just from the other side. :)

Basically, the asterisk means "thing pointed to by".  So "*x" means "the
thing pointed to by x".

Thus, the declaration "int *x" means "the thing pointed to by x is an
integer".  But that doesn't make much sense; you're not declaring the thing
pointed to by x.  Instead, you're declaring x.  What is the type of x?  If
you slide the * over  to get  "int* x", then the rules of C declarations
tell you that x is of type "int*".  So "int *" means "pointer to int".

More generally, the trailing * only shows up in type expressions, and means
that the type under discussion is a pointer to whatever type came before the
*.  (The * is one of the things that gives C "type expressions" instead of
just type names.)

Type expressions are important because  a pointer is not just a memory
address; it's a memory address plus information about what is expected to be
found at that memory address.  A memory address by itself is not useful in C
- you can't dereference it until the compiler knows what type of value to
retrieve from it.  You do that by typecasting - putting a type expression in
parentheses in front of a value tells the compiler "treat this value as this
type".

Typecasting by itself has nothing to do with pointers . . . (int) x means
"treat x as an integer", and can be used whether x is a char or an unsigned
int or a float or whatever.  This is very useful for pointers because the
original meaning of * depends heavily on the type of what comes after.  If x
is a pointer to int, then *x is an int.  If x is a pointer to char, then *x
is a char.  But if you combine the dereferencing with typecasting, you can
get any kind of value out of any pointer.  Which lets you do the C
equivalent of PEEK, among other things.

For example, pretend that at address 0xC000 you have the two bytes 0x01 and
0x02.  Then:

*((char *)0xC000)  is the character '\01'.

 *((int *)0xC000) the integer value 0x0201.

Note that that this assignment:

int x  = *((char *)0xC000);

Will assign 1 to x, not 0x0201.  The whole value is cast to an int because
it's being assigned to an integer variable; you could make that explicit
with another typecast:

int x = (int)(*((char *)0xC000));

but that doesn't change how the pointer is dereferenced.  The inner typecast
does that, and you only ever get a char value out of the expression.

Types are tied to sizes, and this matters when you do arithmetic on pointer
values, because offsets are automatically multiplied by the size of the
thing pointed to.  So given this:

int *x = (int *)0xC000;

Then x+1 is not pointing to 0xC001 but 0xC002.  This is how arrays work in
C: the compiler turns foo[bar] into *(foo+bar).


-- 
Mark J. Reed <markjreed@gmail.com>

----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo@musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Thu May 27 13:21:32 2010

This archive was generated by hypermail 2.1.8 : 2010-05-27 13:21:35 CEST