Skip to main content
GameDev.net gamedev.net
🔒 Locked

Yet another C pointer/array syntax question

Started by Ned_K Dec 7, 2005 at 7:40 AM 7 replies 550+ views
Original Post
Ned_K
Ned_K
I just need to know if I'm thinking this through correctly. Given two pieces of code: ------------------------------------ Code snippet 1: #include void main() { char buffer[5] = {0,1,3,5,7}; char *pbuffer; pbuffer = buffer; printf("%d\n", *pbuffer); printf("%d", *(pbuffer + 4)); } ------------------------------------ Code snippet 2: #include void main() { char buffer[5] = {0,1,3,5,7}; char *pbuffer = buffer; printf("%d\n", *pbuffer); printf("%d", *(pbuffer + 4)); } ------------------------------------ Both of these bits of code yield the same result (on my compiler). Ok, note the bits in bold, namely: char *pbuffer; pbuffer = buffer; and char *pbuffer = buffer; buffer here can mean two very subtley different (but the same) things. It can be treated as a const pointer to buffer[0] or it can be viewed as the address of buffer[0] (i.e., &buffer[0]). In the case of pbuffer = buffer, I am simply assigning the address in the const pointer buffer to be copied into the location pbuffer. In the case of *pbuffer = buffer, the compiler recognizes that this is a pointer operation and simply "points" *pbuffer to the same thing the const pointer buffer is pointing to, namely, the first element of array buffer (and puts the address there just like in the first example). I'm trying to get at the subtle distiction that SEEMS apparent to me since I can have two slightly different expressions(pbuffer = buffer and *pbuffer = buffer) which have identical left-hand sides of the assignment aoperation and different right-hand sides and yet provide exactly the same result. So, I've gone on and on about what is likely dreadfully obvious to most people familiar with the situation here, but these tiny nuances are always my biggest problem (probably because I'm a math major). IF I don't have everything in its proper place in my head I dwell on it far longer than is healthy.
Nitage
Nitage
This expression:
char *pbuffer = buffer;


and this expression:
*pbuffer = buffer;


are totally different.

In the first, the * is part of the type (char*).
In the second, it's a dereference operator.


The line
*pbuffer = buffer;

shouldn't even compile.

Just to clarify: The address of buffer, the address of the first element of buffer and a char pointer to buffer are all exactly the same thing - no difference in any way
Ned_K
Ned_K
Quote:
Original post by Nitage
This expression:
char *pbuffer = buffer;


and this expression:
*pbuffer = buffer;


are totally different.

In the first, the * is part of the type (char*).
In the second, it's a dereference operator.


The line
*pbuffer = buffer;

shouldn't even compile.


Which is what I thought at first too then it did compile!! Hence my confusion and my attempt to rectify and explain the situation in my head.

So you're saying I was on a wild goose chase?
Ned_K
Ned_K
Quote:
Original post by Nitage
This expression:
char *pbuffer = buffer;


and this expression:
*pbuffer = buffer;


are totally different.

In the first, the * is part of the type (char*).
In the second, it's a dereference operator.


The line
*pbuffer = buffer;

shouldn't even compile.

Just to clarify: The address of buffer, the address of the first element of buffer and a char pointer to buffer are all exactly the same thing - no difference in any way


Actually, the two code bits are:

char *pbuffer;
pbuffer = buffer;


and

char *pbuffer = buffer;

It's the second one you don't like right?


I'm pulling that right out of the book I'm using....which I suspect is now wrong.

Maybe I need a new book.
Nitage
Nitage
No, both of those are fine.

The problem is that you are comparing
*pbuffer = buffer


to

pbuffer = buffer


and saying they are the same.

In
char *pbuffer = buffer;


The * doesn't bind to pbuffer - it binds to char, even though you've typed it next to pbuffer.
dimebolt
dimebolt
Quote:
Original post by Ned_K
I'm trying to get at the subtle distiction that SEEMS apparent to me since I can have two slightly different expressions(pbuffer = buffer and *pbuffer = buffer) which have identical left-hand sides of the assignment aoperation and different right-hand sides and yet provide exactly the same result.

Assuming you have your left and rights mixed up (if you really meant to say that they have different right-hand sides I have really have no idea what you mean and you can ignore me), you should look at it differently:
They don't have different left-hand sides because you incorrectly associate the * with the variable name. Consider * part of the type not part of the variable. Writing it like this will perhaps make more sense to you:
char*     pbuffer = buffer; // assigns the pointer (pointing to element 0 of                            // buffer) to pbuffer (which happens to be a char*)orchar*     pbuffer;pbuffer = buffer;           // assigns the pointer (pointing to element 0 of                            // buffer) to pbuffer (which was defined to be a                            // char* on a different line)

Your code means exactly the same thing and will compile to the same executable, but this notation makes it more clear that the * is part of the type.

To add to the confusion the * can also be used as an operator to dereference the pointer and access the pointee directly. In other words *pbuffer also has meaning by itself, for example:
char*     pbuffer;pbuffer = buffer;*pbuffer = 'a'; // the * operator dereferences the pointer, which means                // that *pbuffer is a synonym for buffer[0] and has type                 // char instead of char*.                 // the result of this code is that the contents of buffer[0]                // will be 'a' after the assignment 


Tom
Ned_K
Ned_K
Quote:
Original post by Nitage
No, both of those are fine.

The problem is that you are comparing
*pbuffer = buffer


to

pbuffer = buffer


and saying they are the same.

In
char *pbuffer = buffer;


The * doesn't bind to pbuffer - it binds to char, even though you've typed it next to pbuffer.


Oh, I see. So in the case of the declaration, that * belongs to char and the two expressions then really are exactly the same. Ok, so it was me just looking at the syntax weird. I'm used to seeing the dereference operator in front of the pointer when assigning things so I was starting to think of the two almost as different things.

Ned_K
Ned_K
Thanks guys. That was so simple it's kinda funny. Those are the weird hang-ups when you try to self-teach this stuff.

So the * on pointer declaration (like char *) has nothing at all to do with the dereference operator used in pointer manipulations later in the program.
Zahlman
Zahlman
Well, it does, in the sense of being mnemonic. However, "char*" is the type of the variable, and therefore the * is NOT part of the variable name. pbuffer is the variable, and *pbuffer is the result of dereferencing it.

In C++, where there is more emphasis on making the type system work for you (as opposed to C where typing is simple and void* reigns supreme), it is conventional to write "char* foo" rather than "char *foo". However, this interferes with the unfortunate fact that in "char* foo, bar", bar is declared as a char rather than a char* - even in C++, for reasons of backward compatibility.

See more here.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.