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?
CodePudding user response:
Lets see this step by step:
int firstvalue = 5, secondvalue = 15;
This initializes two 4 byte integers.
---------------------------------------
| | |
| firstvalue (5) | secondvalue (15) |
| | |
---------------------------------------
- Initializes int pointers and sets their values
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
- Now you assign 10 to *p1. What this does is that it modifies the value at the memory address which was stored in p1:
*p1 = 10;
---------------------------------------
| (*p1) | (*p2) |
| firstvalue (10) | secondvalue (15) |
| ^^ | |
---------------------------------------
p1 p2
- Now you assign
*p1
to the memory address stored inp2
.*p1
dereferences the pointerp1
and returns you the value it is pointing to.
*p2 = *p1;
---------------------------------------
| (*p1) | (*p2) |
| firstvalue (10) | secondvalue (10) |
| | ^^ |
---------------------------------------
p1 p2
- Now you change the memory address p1 is pointing to. Now p1 and p2 points to the same variable
p1 = p2;
---------------------------------------
| | (*p1) (*p2) |
| firstvalue (10) | secondvalue (10) |
| | |
---------------------------------------
p1 p2
- Finally, you modify the value at the memory address stored by p1, (that is also p2).
*p1 = 20;
---------------------------------------
| | (*p1) (*p2) |
| firstvalue (10) | secondvalue (20) |
| | ^^ |
---------------------------------------
p1 p2
CodePudding user response:
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
CodePudding user response:
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.
CodePudding user response:
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;
CodePudding user response:
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.
Values
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";
References
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.
- I call my father “Dad”.
- Dad’s friends call him “Bill”.
- My friends call him “Mr. Greer”.
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.
Pointers
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.
WHAT YOU MEANT TO ASK
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:
“What happens if we assign an un-dereferenced pointer to another un-dereferenced pointer?”
... and un-dereferenced means not dereferenced, so you are basically asking:
What happens when we assign one pointer to another?
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