Pointer Syntax

I'm starting this so as not to unfairly clog up this other Thread

In that Thread @YemSalat kindly posted the following

YemSalat: Yeah, it does require a bit of getting used to.

It boils down to:

int* pt; // pointer to an integer
int num; // integer value

// turn a pointer into a value with *:

int num2 = *pt; // integer value

// turn a value into a pointer with &:

int* pt2 = # // pointer to an integer

It nicely illustrates my confusion with the syntax.

In the first line it has int* pt; but later it has int num2 = *pt; where I would expect to need int num2 = &pt;

How can * both extract the address of a variable and extract the value from that address ?

...R

Well, that's the 'c' language syntax.

When declaring a pointer (for example to an integer), use the ''. When you want the contents of a pointer, use also the ''.

There must be some kind of logical argument behind it, but I don't see it either :confused:

Just remember that the '&' is always the address of a variable (or the reference in c++).

int num = 1; int *pt = &a; *pt += 1; //now num == 2 (and pt's value is a pointer to the location of a in memory)

Peter_n: There must be some kind of logical argument behind it, but I don't see it either :confused:

completely logical - if you read '*' as meaning "the content"

int *p; //declare a pointer called p, the CONTENT of which will be of type int

int n = *p; //declare an int called n and assign the CONTENT of p (an int) to it

As I said before - your confusion is 100% justified because the C syntax for pointers does not follow 'straigth forward' rules, it is something that you just have to remember. (It will totally make sense to you once you do)

So the star '*' sign is used to do two things (most of the times): - declare a variable that holds a pointer - 'resolve' a pointer variable into its value

int num = 100;
int * pt; // here '*' is used to declare a pointer

*pt = num; // here '*' is used to make it so that the value of 'num' is assigned to the VALUE of pt variable
num = *pt; // here '*' is used to resolve the value stored in the pt address
[/ode]

The ampersand '&' sign is used to get values by reference:

[code]
int &a = b; // does not assign the same VALUE as 'b' to 'a', but rather points to the location where 'b' is

The main difference between '' and '&' is that pointers () - can be reassigned, while references (&) can not. So in lamens terms - you use a pointer when the variable (or whatever) it is pointing to can be changed. And you use references to point to particular variables and its always gonna be referencing only that particular variable.

Again, in C the syntax for pointers does not follow any 'natural logic' (for a lack of a better term) rules - you'll just have to remember it, but once you get used to them - I am sure you will have 0 problems.

int *p; //declare a pointer called p, the CONTENT of which will be of type int

Years ago I read ("Effective C++", I think, or was it "C++ Primer"?) a "best practice" was to have the asterisk closer to the type than to the variable, so it becomes more intuitive to understand:

int*  p; // use this more intuitive format
int  *p; // rather than this

florinc: Years ago I read ("Effective C++", I think, or was it "C++ Primer"?) a "best practice" was to have the asterisk closer to the type than to the variable, so it becomes more intuitive to understand:

int*  p; // use this more intuitive format
int  *p; // rather than this

The major problem I have with that is with this statement:

int* p, q;

What type is q? It is an int, not a pointer. Having the * with the variable means that you type:

int *p, *q;

which makes it clear that q is a pointer, too.

I guess it's a matter of preference. I usually include comments after declarations, so my code would look like this:

int*  p; // this pointer is used for ....
int*  q;  // this pointer is used for something else :)

"Major problem" solved :)

florinc: int*  p; // use this more intuitive format int  *p; // rather than this

This is another example of my confusion. Clearly the compiler does not care which style is used. But it would be much simpler (and consistent) if the name of a pointer had to be (for example) *p wherever that pointer item is referenced.

That would be similar to the convention in Ruby where class names start with a capital.

YemSalat: The main difference between '' and '&' is that pointers () - can be reassigned, while references (&) can not.

Maybe I am learning something new here. I have always assumed that & was the opposite (or complement) of *. In other words, * gets the address of a variable and & gets the value of the variable at the address. For example int abc = 12; int *def = *abc; int xyz = &def; // would have the value 12

Maybe one could define macros addressOf and valueAt but that would not make it any easier to read code someone else wrote.

...R

int *def = *abc;

Probably a typo (you realize that this does not compile, don't you).

The syntax is logical and consistent.

int *p;

That declaration states that *p is an int, so p must be a pointer to int.

It gets better!

int (*f)();

That declares that (*f)() is an int (or yields an int), so f must be a pointer to a function.

Robin2: I have always assumed that & was the opposite (or complement) of *. In other words, * gets the address of a variable and & gets the value of the variable at the address.

You've got that exactly backwards. & is the "address of" operator, and returns the address of a variable. * is the pointer de-reference operator, and returns the value of the variable a pointer points to.

Also, when talking c++, rather than c, & can be the reference operator, which is basically syntactic "candy" to make use of pointers more straight-forward.

Regards, Ray L.

Ray is right and it seems that we're making it harder than it needs to be. The asterisk is the indirection operator and it tells the "path" that must be taken to fetch an rvalue from a specified address. The address of operator (&) says to fetch a variable's lvalue (memory address) instead of its rvalue (the value it stores).

When it comes to parsing a complex declaration, my Right-Left Rule might help:

http://jdurrett.ba.ttu.edu/3345/handouts/RL-rule.html

For example:

double (*(*pf)())[3][4];

is fairly easy to figure out when you use the Right-Left Rule.

Finally, I think Paul makes a really strong argument for tying the asterisk to the identifier, as in:

int *ptr;

The purpose of the asterisk is to modify the identifier so the compiler treats it differently. His example of defining two variables in a single statement illustrates the problem very clearly.

Robin2: That would be similar to the convention in Ruby where class names start with a capital.

Most OOP languages have this convention, its just that more recent languages tend to 'enforce' their conventions more then the older ones.

int abc = 12;
int *def = *abc; // as mentioned above - this is an error
// You don't need the '*' in abc;
// int *def = &abc; // this means - declare a pointer named 'def' of type 'int', and point it to variable named 'abc'

Already was mentioned above as well, but you got this one backwards:

int xyz = &def; // would have the value 12

PS

PaulS: int *p, *q; which makes it clear that q is a pointer, too.

I prefer this approach for the same reasoning.

int *def = *abc; // as mentioned above - this is an error

Not necessarily.... It depends on how abc is declared. For example:

int **abc;
int *def = *abc;

would be fine, since abc is a pointer to a pointer to an int, so *abc is a pointer to an int, and *def is also a pointer to an int.

Regards, Ray L.

RayLivingston: Not necessarily.... It depends on how abc is declared. For example:

True, but in his example he clearly declares: int abc = 12; So is in fact an error. (I'll edit my comment to make it more clear)

econjack: Ray is right and it seems that we're making it harder than it needs to be.

Agreed. Having re-read my own comments - I can totally see how they could make it more confusing then it is. I guess its just one of those things that one has to 'get' by themselves, and then its gonna seem logical and they will never have a problem with it again.

Peter_n: Well, that's the 'c' language syntax.

When declaring a pointer (for example to an integer), use the ''. When you want the contents of a pointer, use also the ''.

There must be some kind of logical argument behind it, but I don't see it either :confused:

Just remember that the '&' is always the address of a variable (or the reference in c++).

C language is very old. I think that in the stone age people did not care about logic in syntax. You could freely mix data, address and whatever.

By the way isn't it so that with Arrays you don't need the address operator &, because the name is an address. Confusing?

You could freely mix data, address and whatever.

Probably because you had to, when you were limited to 64k or so of RAM.

LMI: By the way isn't it so that with Arrays you don't need the address operator &, because the name is an address. Confusing?

Yes, array is a kind of a reference in memory anyway (basically the positions where it starts and ends, hence the need to declare its size on initilization) So, you can think of the '[]' during array declaration, as a special sort of '&' that defines a sequence of multiple spaces in memory instead of just one.

And yes, this can be confusing.