Pointers and Functions in C++
From the lectures notes of a course at university, on "call-by-value":
void fun(int *ip) { *ip =100; }
called by
int n=2; int *np; np = &n; fun(np);
would change the value of n to 100.
When we say "int *ip", what exactly do we mean? A pointer of type integer? If so, when we call fun() with np as its argument, shouldn't there be an error as np has the address of n, which is not an integer?
开发者_StackOverflowAnd then, we change the value of ip to 100, so doesn't that mean that n now has the value that's in the "memory slot" with the address 100? I am sure I am missing something. :)
A pointer of type integer?
No, a pointer to an integer.
when we call fun() with np as its argument, shouldn't there be an error as np has the address of n, which is not an integer?
n
is an integer so there’s no problem. &n
, np
and ip
all have the same type in your code: int*
.
And then, we change the value of ip to 100
No … we change the value of *ip
, not of ip
. That is, we change the value that ip
points to (which is also sometimes called the pointee).
Yes, when you use int *
as a parameter type of fun
you are saying it accepts a pointer to an int. Since np
is a pointer to an int passing it into fun
is ok.
np
and ip
are pointing to the address of n
, so when you assign a value like *ip = 42
, it will assign the value of 42 to the memory location that ip
is pointing to - which is n
.
What you have in the sample code is called pass by pointer. Your function has a parameter of type pointer to integer. So the value passed to the function is the address of the variable n
. The function assigns 100
to the variable (i.e. a memory location) pointed to by the pointer parameter ip
. The star *
is the dereference operator in C/C++.
in fun(), you aren't changing the value of ip to 100, you're changing the at the memory location pointed to by ip.
type*
used as a type means "a pointer to that type"
common use is int *var
, but I like to write it as int* var
as that makes it a better distinction from dereferenceing a pointer, i.e. *ptr
.
so int* a
means, a is a pointer to an object of type int, *a
means the object pointed to by a and &a
means the address of object a.
think of np
as of type int*
. Bear in mind that for this purpose the asterisk and the int
together make a "pointer to int" type, and are not separatable.
ip
is a pointer, with ip*
you access the "memory slot" it's pointing to. np
is also a pointer. Using &n
you assign the address of the memory slot of n
to np
. So when calling fun()
, inside fun()
the only memory slot that's accessed is the one of n
and thus to n
100 is assigned.
Some confusion is possible here because both n and np store numbers - however, when compiling, the compiler will use the numbers differently; that is, while
n++;
and
np++;
are both actually arithmetic operations, the generated assembly is different. It is important to remember that, ultimately, all of the data in the computer are numbers. They become different types of data merely because we treat them differently.
Specifically with regards to your example,
*np = 100;
you need to remember that the *
means dereference, and that operation happens before the assignment. It may be clearer with superfluous parenthesis:
(* (np) ) = 100;
or in a different context:
int n = *np;
Now, I must say, it warms my heart when you say,
we change the value of ip to 100, so doesn't that mean that n now has the value that's in the "memory slot" with the address 100? as it belies what I regard as an important understanding. However, I believe I am right when I say, you must go out of your way to do that kind of thing to pointers:
static_cast<int>(np) = 100;
This would do what you described, because it tells the computer to treat the number that is np as a different kind of number; in the same way that static_cast<char*>(np)
would treat the number np points to as a character, rather than as an integer.
精彩评论