例子1:
int main(){/* 引用基本使用作用:给变量起别名语法:数据类型 &别名 = 原名*/int a = 10;int b = 20;//int &c//错误,引用必须初始化int& c = a; //一旦初始化后,就不可以更改 c = b; //赋值操作,非更改引用,此时修改了c,则a同时改变//注:输出 a、b、c 值都为20cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;system("pause");return 0;}
例子2:
int main(){int a = 3;int& b = a;int c = a;cout << "a:" << a << endl;cout << "b:" << b << endl;cout << "c:" << c << endl;b = 10;cout << "a:" << a << endl;cout << "b:" << b << endl;cout << "c:" << c << endl;cout << "&a:" << &a << endl;cout << "&b:" << &b << endl;cout << "&c:" << &c << endl;system("pause");return 0;}输出:a:3b:3c:3a:10b:10c:3&a:00000026644FF864&b:00000026644FF864&c:00000026644FF8A4//可以看出a和b的地址相同
例子3:
#include <iostream>using namespace std;//1.值传递void swapA(int a, int b){int tmp = a;a = b;b = tmp;}//2.地址传递void swapB(int* value1, int* value2){int tmp = *value1;*value1 = *value2;*value2 = tmp;}//3.引用传递void swapC(int& a, int& b){int tmp = a;a = b;b = tmp;}int main(){int a = 10;int b = 20;//swapA(a,b);//值传递,形参不会修饰实参//swapB(&a,&b); //地址传递,形参会修饰实参swapC(a, b); //引用传递,形参会修饰实参cout << "a=" << a << ", b=" << b << endl;system("pause");return 0;}
值传递:
这个比较简单,实参a 原本指向地址 1638212,代表1638212这个地址的值是10。在swapA函数中,实参a将值拷贝给形参a,形参a此时也在内存中拥有另外一个地址,地址= xxxx,值为10,在所有的函数体内的操作,都是对 xxxx这个地址的操作,所以并不会影响实际参数的值。
地址传递:
在这里我们习惯把指针写成int* a,int* b而不是int *a,int *b。我们可以这样理解:指针是一种特殊的数据类型,若 int c = 5;int* a = &c;则a是一个指针变量,它的值是c的地址!星号“*”是一个取值操作,和号“&”是一个取址操作。
由于函数传入的是地址,而函数体内又对地址进行取值和赋值操作,所以相对应的地址的值发生了改变。但是地址并没有实际改变,从函数的输出来看,a的地址并不会改变。在C语言中,函数在运行的时候会对每个变量分配内存地址,分配之后只要变量不被销毁,这个地址不能改变。&a = &b;是无法编译通过的。
引用传递:
引用是变量的一个别名,调用这个别名和调用这个变量是完全一样的。所以swapC的结果可以解释。值得注意的是,由于引用时别名,所以引用并不是一种数据类型,内存并不会给它单独分配内存,而是直接调用它所引用的变量。这个与地址传递也就是指针是不一样的(也就是说一个指针虽然指向一个变量,但是这个指针变量在内存中是有地址分配的)
就是说,引用的这个别名,没有重新分配地址(和值传递的重要区别),所以对别名修改,就是对待交换的值修改。
如果觉得《C++:值传递 指针传递 引用传递》对你有帮助,请点赞、收藏,并留下你的观点哦!