Sign in to follow this  
nuclear123

Pointer help

Recommended Posts

struct Player
{
int health;
float healthRegen;
int *armor;
};
int armorvalue = 75;

Player MyPlayer = { 10, 20.0, &armorvalue };
Player *g_pMyPlayer = &MyPlayer;
Player **g_ppMyPlayer = &g_pMyPlayer;

int main()
{





MyPlayer.health; // health value
*MyPlayer.armor; // armor value

g_pMyPlayer->health; // health value
*g_pMyPlayer->armor; // armor value






return 0;
}

1.) how do i obtain the health value and armor value using the double pointer variable called **g_ppMyPlayer
2.) Also how are these implemented without using the -> operator and only using parenthesis and *?

Share this post


Link to post
Share on other sites
[quote name='Serapth' timestamp='1318892876' post='4873673']@TheUnbeliever, you are missing an *. Its a pointer to a pointer to a reference, thus two levels of onion peeling.[/quote]

What? It's a Player** - a pointer to a pointer to a player. We dereference once to get a Player* and again to get a Player (or use -> to get the member directly). &v gives you a T* where T is the type of v.

In any case, a pointer to a reference isn't a meaningful concept, as far as I know. A reference is, for all intents and purposes, the original object. You'd just get a plain ol' T*.

Share this post


Link to post
Share on other sites
[quote name='TheUnbeliever' timestamp='1318893846' post='4873682']
[quote name='Serapth' timestamp='1318892876' post='4873673']@TheUnbeliever, you are missing an *. Its a pointer to a pointer to a reference, thus two levels of onion peeling.[/quote]

EDIT: Argh, just realized my mistake, sorry TheUnbeliever, I missed the you were dealing with health in your example, not armor.


What? It's a Player** - a pointer to a pointer to a player. We dereference once to get a Player* and again to get a Player (or use -> to get the member directly). &v gives you a T* where T is the type of v.

In any case, a pointer to a reference isn't a meaningful concept, as far as I know. A reference is, for all intents and purposes, the original object. You'd just get a plain ol' T*.
[/quote]

No, a ref is more akin to a const pointer to the original object, now when passing a value by reference, it feels like you are using a native object, but when assigning a pointer to a reference, you are essentially creating a const pointer to the objects location.


What this sample is dealing with is a pointer to a pointer to an object. Therefore to access it, you need to ** twice, once to resolve the pointer to a pointer, and once to resolve the pointer to the pointed at object. Then in this particular case, since the structure member ( armor ) again is a pointer, to use "." syntax, it needs to be *'ed once again. More simply, just try to compile the code you gave him, without another dereference your code will not work. Since he asked to deal with "." access, you need a double dereference first.

Ok, that came out poorly. What I am saying is, your example either needs to be:

*(*g_ppMyPlayer)->armor
or
*(**g_ppMyPlayer).armor // if you want to use . instead of ->



As to the OP, by parentheses, do you mean square brackets?

So you want to access your pointer like
g_ppMyPlayer[0][0].armor?

Share this post


Link to post
Share on other sites
Just to be clear: there are no references in the above code, at all. If you create a reference, and then create a pointer from this reference, you do not need an additional use of the indirection operator (*). That is, the following code is correct.

[source lang="cpp"]int main()
{
int x = 0;
int& x_ref = x;

int* x_ptr = &x_ref; // points to x
*x_ptr = 1; // x is 1
}[/source]

However, it is certainly the case that you need an additional indirection to access the value pointed at by the armor member above, because this is itself a pointer. So you'd have something like *((*g_ppMyPlayer)->armor) which is ugly as sin. The member itself - the pointer - is still accessed exactly the same as health: (*g_ppMyPlayer)->armor.

[quote name='nuclear123' timestamp='1318895829' post='4873689']
I'm trying to understand reading complex pointers and would like to know the many different ways each of these can be implemented using -> , * , and []
[/quote]

p->x is identical to (*p).x
p[i] is identical to *(p+i)

Share this post


Link to post
Share on other sites
1.) are the following equivalent



[code]
*MyPlayer.armor;
*(MyPlayer).armor;
*(MyPlayer.armor);
MyPlayer.armor[0];


(*g_pMyPlayer).armor
*(g_pMyPlayer->armor)
g_pMyPlayer[0].armor

*(**g_ppMyPlayer).armor;
*(*g_ppMyPlayer)->armor;
g_ppMyPlayer[0][0].armor;[/code]

im wanting to understand how to fully manipulate pointers in doing what i want and being able to read others code when they use different styles of derefernceing.

Share this post


Link to post
Share on other sites
[quote name='Serapth' timestamp='1318892876' post='4873673']
@TheUnbeliever, you are missing an *. Its a pointer to a pointer to a [b][u]reference[/u][/b], thus two levels of onion peeling.
[/quote]
[quote name='TheUnbeliever' timestamp='1318896530' post='4873691']
Just to be clear: there are no [b][u]references [/u][/b]in the above code, at all.
[/quote]
FYI, I think that's where the misunderstanding is coming from between you too :)

[quote name='nuclear123' timestamp='1318900704' post='4873709']
1.) are the following equivalent
[/quote]
Most of them, no. I think what would help you is really understanding how pointers actually work -- what they really are. They just point to a memory address. Somewhere in memory. Anywhere in memory. And that's all a pointer stores. Is a memory address.

You have to use * to access the memory that is stored in that memory address that the pointer points to. -> is shorthand for (*pointer).member; so you can do pointer->member instead. That is, -> is used to access the members of a data structure from a pointer, just like . is used to access the members of a regular data structure. -> and * are very different, seeing as * has nothing to do with the data structure's members.

pointer[x] is the same as *(pointer + x), like has been said. That is, it takes the memory address stored in the pointer, advances it by x units (so now its a new memory address, x units away from the original memory address), and then it deferences the pointer to access the actual data stored in the memory at that advanced location.

For the record, pointer[0] is the same as *pointer (that is, *(pointer + 0) is the same as *(pointer)), but you shouldn't just mix the two casually. [] is used for arrays, and * is used for non-arrays; using * on an array or [] on a non-array is something you should only do if you really, really know what you're doing.

I remember watching [url="http://video.google.com/videoplay?docid=3796146278554348828"]this video[/url] years ago, and it helped me understand things.

Share this post


Link to post
Share on other sites
Answers in line below:
[quote name='nuclear123' timestamp='1318900704' post='4873709']
1.) are the following equivalent
[/quote]

All the 1st ones are the same. The . takes precedence over *, so all of these you are getting the value pointer at by armor
[code]
*MyPlayer.armor;
*(MyPlayer).armor;
*(MyPlayer.armor);
MyPlayer.armor[0];
[/code]

These below are not the same, see my comments after each line
[code]
(*g_pMyPlayer).armor
// The above value will be the address of armor, you need to do this:
// *(*g_pMyPlayer).armor

*(g_pMyPlayer->armor)
// the above is fine

g_pMyPlayer[0].armor
// This one is the same as the 1st. The value will be the ponter to armor, you need to do this:
// *g_pMyPlayer[0].armor or
//
[/code]
The below are almost the same, (ie, you get the value of the data armor points to) the last one is not.
[code]
*(**g_ppMyPlayer).armor;
*(*g_ppMyPlayer)->armor;
g_ppMyPlayer[0][0].armor;
// This one is almost right, you still need to go one deeper with *
// *g_ppMyPlayer[0][0].armor;
// however, I would not recommend using ** like this
[/code]

[quote]
im wanting to understand how to fully manipulate pointers in doing what i want and being able to read others code when they use different styles of derefernceing.
[/quote]


Share this post


Link to post
Share on other sites
[quote name='BeerNutts' timestamp='1318963684' post='4873996']
Let me add, for simplicity, when I'm using pointers, or pointer to pointer, I use () to ensure where the indirection is:
[code]

*((*g_pMyPlayer).armor)
// or, simply
*(g_pMyPlayer->armor)

// and
*(MyPlayer.armor)
[/code]
[/quote]
This. Putting the parentheses in the right places really helps code clarity, even if they aren't technically necessary due to operator precedence.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this