先上测试代码:
#include<iostream>
using namespace std;
// 变量作为函数参数
void swap1(int a, int b) {
int t;
t = a;
a = b;
b = t;
}
// 指针作为函数参数
void swap2(int *a, int *b) {
int t;
t = *a;
*a = *b;
*b = t;
}
// 引用作为函数参数
void swap3(int &a, int &b) {
int t;
t = a;
a = b;
b = t;
}
// 指针的指针作为函数参数
void move1(int *a) {
a = a+1;
}
void move2(int **a) {
*a = *a+1;
}
int main() {
int x(5), y(10);
cout<<"变量作为函数参数:"<<endl
<<"x="<<x<<", y="<<y<<"\nswap1: ";
swap1(x,y);
cout<<"x="<<x<<", y="<<y<<endl;
int *px=&x, *py=&y;
cout<<"\n指针作为函数参数:"<<endl
<<"x="<<x<<", y="<<y<<"\nswap2: ";
swap2(px,py);
cout<<"x="<<x<<", y="<<y<<endl;
cout<<"\n引用作为函数参数:"<<endl
<<"x="<<x<<", y="<<y<<"\nswap3: ";
swap3(x,y);
cout<<"x="<<x<<", y="<<y<<endl;
cout<<"\n指针的指针作为函数参数:"<<endl;
int a[] = {1,2,3,4};
int *pa = a;
cout<<"a[0]: "<<a[0]<<endl
<<"调用move1前*pa="<<*pa<<endl;
move1(pa);
cout<<"调用move1后*pa="<<*pa<<endl;
move2(&pa);
cout<<"调用move2后*pa="<<*pa<<endl;
}
输出为
变量作为函数参数:
x=5, y=10
swap1: x=5, y=10
指针作为函数参数:
x=5, y=10
swap2: x=10, y=5
引用作为函数参数:
x=10, y=5
swap3: x=5, y=10
指针的指针作为函数参数:
a[0]: 1
调用move1前*pa=1
调用move1后*pa=1
调用move2后*pa=2
swap1()
swap1()中开辟新的内存空间分配给a和b,并非别被赋值x、y,swap1()中a和b交换了值,但随着swap1()退出,a、b的内存空间被清理,并未改变x、y的值,因此交换值失败。
swap2()
swap2()用指针作为形参,传入的是x和y的地址,在swap内部直接对x和y进行操作,因此交换值成功。
swap3()
swap3()用引用作为函数形参,在swap内部并未开辟新的内存空间,是直接对x和y进行的操作,a和b只是相当于x和y的别名(可参见引用的定义),因此交换成功。
move1()
move1的本意是想改变指针,因此将指针输入move1(),但无奈move1()的形参是个指针,随着move1()退出,形参被从内存中清理,并没有影响pa,move失败。
(以下是复杂解释,可忽略。。。)
move1()用指针作为函数形参。指针pa表示开辟了一块内存用来存数组a首元素的地址。在move1()中,又开辟了一块新内存作为局部变量指针a,这个局部变量a被pa赋值,相当于局部变量a内存着数组a的首元素地址,即指针a指向数组a的首元素。move1()内部+1操作使得局部指针a指向数组a的第二个元素。但随着move1()退出,局部指针a被清理出内存,并没有影响到外部指针pa,因此move失败。
move2()
为改变指针pa,move2()用指针的指针作为形参,与swap2()异曲同工,真是可爱。