Reputation: 3
I can't understand what happens after line *p1=10
, what happens with *p2
variable, and in the end how does secondvalue
variable gets 20.
#include <iostream>
using namespace std;
int main ()
{
int firstvalue = 5, secondvalue = 15;
int * p1, * p2;
p1 = &firstvalue;
p2 = &secondvalue;
*p1 = 10;
*p2 = *p1;
p1 = p2;
*p1 = 20;
cout << "firstvalue is " << firstvalue << '\n';
cout << "secondvalue is " << secondvalue << '\n';
return 0;
}
Output of command
firstvalue is 10
secondvalue is 20
I can't understand how the secondvalue
variable gets a value of 20.
If we assigned *p2=*p1
mustn't secondvalue
variable get 10?
Upvotes: 0
Views: 95
Reputation: 10073
So, pointers and references (and de-referencing, oh my!)
Alas, this is where vocabulary makes a difference, and people love this particular selection of vocabulary. So here it is, explained in all its glory.
A value is something that exists somewhere in memory (like a variable, though not necessarily). To be useful, we programmers like to give values both a type and a name.
int x = 74;
double pi = 3.141592;
string name = "Hannah";
A direct reference is an alias, another name, if you will, for a value.
int x = 7; // type:int, name:x, value:7
int& z = x; // z = another name for x
z = 12; // x = 12;
Using aliases is something we do in normal life.
Different names. Same person.
Now, some C++ purists will tell you these are just plain references. Well, yes... and no. Yes, as far as the C++ Language is concerned. No, as far as understanding things is concerned. Just remember that when talking to C++ people, the word “reference”, unless otherwise qualified with some adjective, always means direct reference, or alias.
Before C++ introduced “references” as part of the language abstraction, we had indirect references — also called pointers.
It is indirect because a pointer is not itself a reference. But you can get a reference from a pointer’s value by dereferencing it using the *
operator.
The term is a bit wonky (because it looks like you are “un”-referencing it), but the opposite is true: you are taking that indirect reference (the pointer value) and effectively converting it into an (unnamed) direct reference, an alias for the “pointed-to” (or “referenced”) value.
int x = 7;
int* px = &x; // type=(pointer to int) name=“px” value=(address of x)
*px = 12; // (direct reference to x) = 12
In other words px
is a pointer with an indirect reference to — i.e. address of — x
.
Thus when we dereference px
with the *
operator, we transform the expression into a direct reference to x
— at which point we have access to read or modify x
’s value just as if we had x
in hand to begin with.
I suspect the term “dereference” came about because we are “un”-indirect referencing a pointer value to obtain a direct reference, but all the people who created the term are dead now and I don’t know of any place they felt the need to explain it.
So, a dereferenced pointer is an alias for the target object. You want to know what happens if you don’t dereference the pointers, which would be:
... and un-dereferenced means not dereferenced, so you are basically asking:
The answer at this point should not be a surprise: the same thing that happens whenever we assign any variable’s value to another.
int x = 7;
int* p1 = &x; // p1 now “points to” x
int* p2 = p1; // and now p2 also “points to” x
Remember, the value of a pointer is the address of another object in memory, and you can copy values around however you like.
*p2 = 42; // x = The Answer
Upvotes: 0
Reputation: 118
Yeah, but when you p1 = p2;
you make so p1 now stores the reference to second value, and in the line below you assing *p1 (this is secondvalue) to 20.
So in your code flow firstvalue is assigned to 10 on *p1 = 10;
and secondvalue is assigned to 20 on *p1 = 20;
Upvotes: 0
Reputation: 375
Lets see this step by step:
int firstvalue = 5, secondvalue = 15;
This initializes two 4 byte integers.
---------------------------------------
| | |
| firstvalue (5) | secondvalue (15) |
| | |
---------------------------------------
int * p1, * p2;
p1 = &firstvalue;
p2 = &secondvalue;
p1 now stores the address of firstvalue, and p2 stores the address of secondvalue
---------------------------------------
| (*p1) | (*p2) |
| firstvalue (5) | secondvalue (15) |
| | |
---------------------------------------
p1 p2
*p1 = 10;
---------------------------------------
| (*p1) | (*p2) |
| firstvalue (10) | secondvalue (15) |
| ^^ | |
---------------------------------------
p1 p2
*p1
to the memory address stored in p2
. *p1
dereferences the pointer p1
and returns you the value it is pointing to.*p2 = *p1;
---------------------------------------
| (*p1) | (*p2) |
| firstvalue (10) | secondvalue (10) |
| | ^^ |
---------------------------------------
p1 p2
p1 = p2;
---------------------------------------
| | (*p1) (*p2) |
| firstvalue (10) | secondvalue (10) |
| | |
---------------------------------------
p1 p2
*p1 = 20;
---------------------------------------
| | (*p1) (*p2) |
| firstvalue (10) | secondvalue (20) |
| | ^^ |
---------------------------------------
p1 p2
Upvotes: 1
Reputation: 118435
If we assigned *p2=*p1 mustn't secondvalue variable get 10?
It sure does. And if that was the last assignment, then that what would happen. But perhaps you've noticed that there are more assignments, that follow this one:
p1 = p2;
p1
is now pointing to the same value that p2
is pointing to. p2
is pointing to secondvalue
, so p1
is now pointing to secondvalue
, too.
*p1 = 20;
The value that p1
points to gets assigned 20
. And that's how secondvalue
gets assigned 20.
Upvotes: 1
Reputation: 8998
p1 = p2;
This doesn't copy the value pointers point to, just "address" the p2
points to. Thus at this point both p1
and p2
point to the secondvalue
, and changing either of them applies changes to the secondvalue
Upvotes: 1