book.
Modifying the outside object
Ordinarily, when you pass an argument to
a function, a copy of that argument is made inside the function. This is
referred to as
pass-by-value. You
can see the effect of pass-by-value in the following program:
//: C03:PassByValue.cpp
#include <iostream>
using namespace std;
void f(int a) {
cout << "a = " << a << endl;
a = 5;
cout << "a = " << a << endl;
}
int main() {
int x = 47;
cout << "x = " << x << endl;
f(x);
cout << "x = " << x << endl;
} ///:~
In f( ), a is a
local variable, so it
exists only for the duration of the function call to f( ). Because
it’s a function argument,
the value of a is initialized by the arguments that are passed when the
function is called; in main( ) the argument is x, which has a
value of 47, so this value is copied into a when f( ) is
called.
When you run this program you’ll
see:
x = 47
a = 47
a = 5
x = 47
Initially, of course, x is 47.
When f( ) is called, temporary space is created to hold the variable
a for the duration of the function call, and a is initialized by
copying the value of x, which is verified by printing it out. Of course,
you can change the value of a and show that it is changed. But when
f( ) is completed, the temporary space that was created for a
disappears, and we see that the only connection that ever existed between
a and x happened when the value of x was copied into
a.
When you’re inside
f( ), x is the
outside object (my
terminology), and changing the local variable does not affect the outside
object, naturally enough, since they are two separate locations in storage. But
what if you do want to modify the outside object? This is where pointers
come in handy. In a sense, a pointer is an alias for another variable. So if we
pass a pointer into a function instead of an ordinary value, we are
actually passing an alias to the outside object, enabling the function to modify
that outside object, like this:
//: C03:PassAddress.cpp
#include <iostream>
using namespace std;
void f(int* p) {
cout << "p = " << p << endl;
cout << "*p = " << *p << endl;
*p = 5;
cout << "p = " << p << endl;
}
int main() {
int x = 47;
cout << "x = " << x << endl;
cout << "&x = " << &x << endl;
f(&x);
cout << "x = " << x << endl;
} ///:~
Now f( ) takes a pointer as
an argument and dereferences the pointer during assignment, and this causes the
outside object x to be modified. The output is:
x = 47
&x = 0065FE00
p = 0065FE00
*p = 47
p = 0065FE00
x = 5
Notice that the value contained in p
is the same as the address of x – the pointer p does
indeed point to x. If that isn’t convincing enough, when p
is dereferenced to assign the value 5, we see that the value of x is now
changed to 5 as well.
Thus, passing a pointer into a function
will allow that function to modify the outside object. You’ll see plenty
of other uses for pointers later, but this is arguably the most basic and
possibly the most common
use.