C++ pointers local in functions
This is a code snippet I created for learning purposes in C++, I am currently trying to teach myself. My question is:
Why does *ptr = 30
change the output values of the two last cout statements in my main? (the output is 30, 30, 30). Consequently, why does int y = 30;
and ptr = &y;
not change the output in my main, and stay local to the function? (if I comment out *ptr = 30, and not the former two statements, the output is 30, 5, 5)
If I change the function input to void printPointer(int *&fptr)
-- and comment out only *ptr = 30
-- then *ptr
in my main will be modified, but not x. I understand this, as the pass by reference is modifying the pointer, but not how my first statement modifies *ptr and x in my main.
#include 开发者_开发知识库<iostream>
using namespace std;
void printPointer(int *fptr);
int main()
{
int x = 5;
int *ptr = &x;
printPointer(ptr);
cout << *ptr << endl;
cout << x << endl;
return 0;
}
void printPointer(int *fptr)
{
// int y = 30; // this does not change the output of the last two couts in main, output = 30, 5, 5
// fptr = &y;
*fptr = 30; // uncommenting this and commenting out the former two statements: output = 30, 30, 30
cout << *fptr << endl;
}
*ptr = 30
changes the value of what is being pointed at. In your case, you have set ptr
to point at x
(when you did ptr = &x
and then passed that in as the argument to printPointer()
). So the value of x
is changed.
When you instead do int y = 30; fptr = &y;
, all you're doing is changing fptr
to point at a different variable. That's it. You're not changing the value of what is being pointed to (i.e. the value of x
). And you're not affecting ptr
, because fptr
is a separate, local, variable. So ptr
still points at x
, and x
is still 5.
When you modify your function to take the pointer by reference, then changing fptr
to point at y
also changes ptr
, because they are the same variable.
*fptr = 30
would dereference the address stored in fptr
and write 30 at the position in memory. this address in memory you gave to the function with printPointer(ptr)
. ptr
in this case was the address of x, which you assigned to ptr with ptr = &x
.
int y= y
declares a variable local to the function.
fptr = &y
assigns the address of y to fptr (and overwrites the value from ptr). so the last line in this case would change the local variable y instead of x.
If I understand correctly, you're asking about two pieces of code. The first one is what you posted:
#include <iostream>
using std::cout;
void f(int* fptr) {
*fptr = 30; // 11
cout << "*fptr = " << *fptr << '\n'; // 12
}
int main() {
int x = 5; // 1
int* ptr = &x; // 2
f(ptr); // 21
cout << "*ptr = " << *ptr << '\n'; // 22
cout << "x = " << x << '\n'; // 23
}
In this case, the pointer always points to x, and in the function, you still change the value of x, as that is what fptr is pointing to. If it helps, here's a demonstration of the value of the variables at the end of every line: NE means a variable does not currently exist.
1. x = 5, ptr = NE, fptr = NE
2. x = 5, ptr = &x, fptr = NE
11. x = 30, ptr = &x, fptr = &x
12. x = 30, ptr = &x, fptr = &x
21. x = 30, ptr = &x, fptr = NE
After that, the values do not change, and all three statements will print 30.
The second one is:
#include <iostream>
using std::cout;
void f(int*& fptr) {
int y = 30; // 11
fptr = &y; // 12
cout << "*fptr = " << *fptr << '\n'; // 13
}
int main() {
int x = 5; // 1
int* ptr = &x; // 2
f(ptr); // 21
cout << "*ptr = " << *ptr << '\n'; // 22
cout << "x = " << x << '\n'; // 23
}
In the first case, the pointer is passed by reference, and it points to y. In fact, in this case, line 21 involves undefined behaviour, as y no longer exists. Again, line-by-line analysis:
1. x = 5, y = NE, ptr = NE, fptr == NE
2. x = 5, y = NE, ptr = &x, fptr == NE
11. x = 5, y = 30, ptr = &x, fptr == ptr
12. x = 5, y = 30, ptr = &y, fptr == ptr
13. x = 5, y = 30, ptr = &y, fptr == ptr
21. x = 5, y = NE, ptr = &y, fptr == NE
The values again do not change after this: however, on line 22, you try to take the address of ptr
. As you can see, *ptr = y = NE
, and thus the behaviour is undefined. The output can be anything.
(Another note is that you should avoid using namespace std;
as it can cause name clashes; use using std::cout;
and similar, as in the code above.)
精彩评论