函数传参:值、指针与引用(先不看)¶
值传递¶
普通 int 参数,接收到实参的值,修改的是副本。
#include <iostream>
using namespace std;
void fun(int x) {
x += 5;
}
int main() {
int y = 0;
fun(y);
cout << y; // 输出0
return 0;
}
fun 里的 x,与 main 里的 y 是两个独立变量。
不要由此认定“值传递一定慢,引用一定快”。先看需不需要修改原对象,再看数据类型和使用场景。
指针传参¶
把地址传进去,通过指针修改原变量。
#include <iostream>
using namespace std;
void fun(int *x) {
*x += 5;
}
int main() {
int y = 0;
fun(&y);
cout << y; // 输出5
return 0;
}
调用时传 &y,函数里通过 *x 修改 y。这里要求传入的指针指向有效的 int 对象。
指针本身,也是按值传进去的。 改指针的指向,与改它指向的数据,不是一回事。
引用传参¶
参数直接成为实参的别名。
#include <iostream>
using namespace std;
void fun(int &x) {
x += 5;
}
int main() {
int y = 0;
fun(y);
cout << y; // 输出5
return 0;
}
定义参数时写 int &x,调用时仍然写 fun(y),不用给 y 加取地址符。
这里的 y 要先有确定的值,因为函数中 x += 5 会读取旧值再加 5。
交换两个变量¶
值传递,交换的是副本
引用传参,才能在这里修改原来的两个变量
两组例子分别运行,不要把这两个同名版本同时抄进同一份程序。
改指针,与改指向的数据¶
#include <iostream>
using namespace std;
void f(char *a, char *b) {
a = b;
(*a)++;
}
int main() {
char c1 = 'A', c2 = 'a';
char *p1 = &c1, *p2 = &c2;
f(p1, p2);
cout << c1 << ' ' << c2; // 输出A b
cout << '\n' << (p1 == &c1); // 输出1,p1仍指向c1
return 0;
}
a = b 只改变函数内指针副本 a 的指向,不会把 main 里的 p1 改掉。
随后 (*a)++ 修改的是 c2,所以 c2 从小写 a 变成小写 b。
输出字符变量的地址¶
cout 对 char* 有特殊处理,会把它当成 C 风格字符串。
想输出地址,就先转成 void*。否则拿单个字符的地址当字符串输出,可能一直读到后面的内存。
数组参数¶
这里的数组参数,实际按指向首元素的指针处理,不会复制整个数组。
修改 a[i],会修改调用者数组中的对应元素。长度需要另外传入,不能在函数里用 sizeof a 得到整个数组大小。