Pointers: &, *, and pass-by-pointer · 指针:&、* 与按指针传参
A problem from last lesson
- Last lesson, a function got a copy of your number. Changing the copy did not change the original.
- C copies every argument you pass to a function. So a normal function cannot change your variable.
- To change it, the function needs the variable's address — where it lives in memory.
上一课留下的问题
- 上一课里,函数拿到的是你那个数字的副本。改这个副本,不会改到原来的变量。
- C 会复制你传给函数的每一个参数。所以普通的函数没办法改你的变量。
- 要想改它,函数需要这个变量的地址 —— 也就是它在内存里待的位置。
Every variable has an address
- Think of a variable as a box in memory. The value is kept inside the box.
- Every box has an address: a number that says where the box is.
- The
&operator gives you that address.&xmeans "the address ofx".
每个变量都有一个地址
- 把变量想成内存里的一个盒子,值就放在盒子里面。
- 每个盒子都有一个地址:一个数字,告诉你这个盒子在哪里。
&运算符就能取出这个地址。&x表示“x的地址”。
A pointer holds an address
- A pointer is a variable that stores an address, not a normal value.
- You declare one with a
*:int *p = &x;reads as "ppoints tox". - To reach the value at that address, put
*in front:*p. This is called dereference. - Changing
*pchanges the original variable.*p = 5;puts5intoxitself.
指针保存的是地址
- 指针是一种变量,它保存的是一个地址,而不是普通的值。
- 用
*来声明指针:int *p = &x;读作“p指向x”。 - 要访问那个地址里的值,在前面加
*:*p。这叫做解引用。 - 改
*p就会改到原来的变量。*p = 5;会把5放进x本身。
#include <stdio.h>
void set_to_five(int *p) {
*p = 5; // change the value at the address
}
int main(void) {
int x = 0;
set_to_five(&x); // pass the ADDRESS of x
printf("%d\n", x); // 5 — the original changed!
return 0;
}
Out-pointers: giving back more than one answer
- A function can
returnonly one value. But it can change several variables through pointers. - You pass the address of each answer, like
find(&min, &max). The function writes into them with*. - These extra pointer parameters are called out-pointers. The caller reads the answers after the call.
- A pointer that points to nothing is
NULL. Never dereference aNULLpointer.
传出指针:一次给回多个答案
- 一个函数只能
return一个值。但它可以通过指针改动好几个变量。 - 你把每个答案的地址传进去,比如
find(&min, &max)。函数用*把结果写进去。 - 这些额外的指针参数叫做传出指针。调用之后,调用者就能读到这些答案。
- 一个不指向任何东西的指针是
NULL。绝对不要对NULL指针解引用。
Common mistakes
&xis the address ofx;*pis the value stored atp.- Never use
*pon an uninitialised orNULLpointer.
常见错误
&x是x的地址;*p是p指向的值。- 绝不要对未初始化或
NULL的指针用*p。
Now you try
- Each task gives you a function to complete. Use
*to read or change the value the pointer points to. - When a value comes in through a pointer (like
int *p), write your answer through it — do notreturnit. - Do not write a
main— the checker provides one. Press Run, then Check answer.
现在轮到你了
- 每个任务都给你一个要补全的函数。用
*来读或改指针所指向的值。 - 当一个值是通过指针传进来的(比如
int *p),把答案通过它写回去 —— 不要用return。 - 不要自己写
main—— 检查器会帮你加上。按 Run(运行),然后 Check answer(检查答案)。
Complete void add_one(int *p) so it adds 1 to the int that p points at. Use *p. Do not · 不 write a main — the checker provides one. · 完成 void add_one(int *p),让它把 p 所指向的整数加 1。使用 *p。不要写 main —— 检查器会提供。
Click Run to see the output here. · 点击“运行”查看此处输出。
Complete void swap(int *a, int *b) so it exchanges the two ints. Use a temporary variable. Do not · 不 write a main. · 完成 void swap(int *a, int *b),让它交换这两个整数。用一个临时变量。不要写 main。
Click Run to see the output here. · 点击“运行”查看此处输出。
Complete void min_max(const int a[], int n, int *min_out, int *max_out). Scan the array, then write the smallest value through min_out and the largest through max_out. Assume n >= 1. Do not · 不 write a main. · 完成 void min_max(const int a[], int n, int *min_out, int *max_out)。遍历数组,然后把最小值通过 min_out 写回,把最大值通过 max_out 写回。假设 n >= 1。不要写 main。
Click Run to see the output here. · 点击“运行”查看此处输出。