Pointers
C Programming Lesson 8 2:34 English narration · English + 中文 subtitles burned in
Chapters
Transcript
Two lessons ago something odd happened.
两课之前发生了一件奇怪的事。
A function that added one to an int changed nothing outside, because the copy was changed and then thrown away.
一个给 int 加 1 的函数,对外面毫无影响,因为被改的是副本,然后就被丢掉了。
But a function that doubled an array really did change the caller's data.
但一个把数组翻倍的函数,却真的改动了调用者的数据。
Same language, same kind of call, opposite outcome.
同一种语言,同样的调用方式,结果却相反。
So what does an array have that an int does not?
那么数组有什么是 int 没有的?
The answer is this whole lesson, and it is simpler than its reputation.
答案就是这一整课,而且它比它的名声要简单。
Every variable you make lives somewhere in memory, at a numbered location called its address.
你创建的每一个变量都住在内存里的某个地方,那个带编号的位置叫做它的地址。
Picture a strip of boxes: x holds five and sits at address one thousand; y holds nine and sits just after it.
想象一排盒子:x 装着 5,位于地址 0x1000;y 装着 9,就紧挨在它后面。
Print x and you get the value inside.
打印 x,你得到的是盒子里的值。
But put an ampersand in front and you get the address instead — ampersand asks where, not what.
但在前面加上 &,你得到的就是地址——& 问的是“在哪里”,不是“是什么”。
You have used it already, every time you called scanf.
其实你早就用过它了,每次调用 scanf 的时候。
A pointer is a variable like any other — a box of its own, at its own address — except that what it holds is an address.
指针也是一个普通的变量——它有自己的盒子,自己的地址—— 只不过它装的是一个地址。
Int star p says: p holds the address of an int.
int *p 的意思是:p 里装着某个 int 的地址。
Set it to ampersand x and it holds where x lives.
把它设成 &x,它装的就是 x 所在的位置。
Now the star does the other half of the job: written in front of p, it means go to that address and use the box there.
这时星号做另一半工作:写在 p 前面,它的意思是“去那个地址,用那里的盒子”。
So star p equals star p plus one, and x itself changes to six — without the name x appearing anywhere.
于是 *p = *p + 1,x 本身就变成了 6——而 x 这个名字一次都没出现。
Now the lesson's second task, the one every C course sets: swap two values.
现在做课程里的第二道题,也是每门 C 课都会出的那一题:交换两个值。
The caller passes two addresses, so the function can reach both boxes.
调用者传进来两个地址,所以函数能够到达这两个盒子。
Inside, three lines.
函数里面是三行。
Keep the first one safe in a temporary.
先把第一个值安全地存进一个临时变量。
Copy the second over the first.
再把第二个盖到第一个上。
Then put the saved one into the second.
最后把存起来的那个放进第二个。
Try it without the temporary and watch it fail: the first assignment destroys the value you still needed.
去掉临时变量试试就会失败:第一次赋值就把你还要用的值毁掉了。
Four things to take with you.
带走四点。
One: ampersand x is the address of x.
第一:&x 是 x 的地址。
Two: int star p declares a box that holds an address.
第二:int *p 声明的是一个装着地址的盒子。
Three: star p is the value at that address, so writing to star p writes to the original.
第三:*p 是那个地址上的值,所以给 *p 赋值就是改动原来的那个变量。
Four: that is how a function answers twice — pass in two out-pointers, as the third task does with a minimum and a maximum.
第四:函数就是这样一次给出两个答案的——传进两个输出指针, 就像第三题里的最小值和最大值那样。
Now go and do them.
现在去做吧。