C/C++浅谈引用与传递

Posted AMOKAY

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C/C++浅谈引用与传递相关的知识,希望对你有一定的参考价值。

1. 首先提及引用

C语言并没有,引用是C++引入的重要机制,让C语言中的指针实现的功能有更简洁的实现方式

引用更方便:只需要在定义的时候使用&符号即可,后续的使用完全跟普通变量一样,而其底层的指针实现方式又使其相比于普通变量更方便传递

1.1. 引用与指针的相同点

引用是变量的别名,他不能脱离变量而存在。其实引用本身是一个变量,只不过这个变量的定义与使用不同于一般的变量。

如下为引用的使用,其中变量ri即为一个引用

int i = 5;
int &ri = i;
ri = 8;//可以实现修改i的值
int i = 5;
int* const pi = &i;
*pi = 8;//可以实现修改i的值

由于引用是不能脱离被引用的对象存在的,所以对应的指针为指针常量,也就是指针指向的地方是不能变的。

1.2. 引用与指针常量的不同点

看以下代码:

#include<iostream>
using namespace std;


int main(int argc, char* argv[]) {
int i = 5;
cout<<" i = "<<i<<endl;
cout<<" &i = "<<&i<<endl<<endl;


int* const pi = &i;
cout<<"*pi = "<<*pi<<endl;
cout<<" pi = "<<pi<<endl;
cout<<"&pi = "<<&pi<<endl<<endl;


int& ri = i;
cout<<" ri = "<<ri<<endl;
//cout<<"*ri = "<<*ri<<endl;不能对引用使用*运算符
cout<<"&ri = "<<&ri<<endl;


return 0;
}

结果为:

  i = 5
&i = 0022FBCC


*pi = 5
pi = 0022FBCC
&pi = 0022FBC0


ri = 5
&ri = 0022FBCC


所以,我认为是不是可以简单的以为: int &ri = i等价于int* const pi = *i, 在使用的时候: &ri等价于piri等价于*pi

另外引用与指针的不同还有如下:

1.指针变量具有n级/多级间接寻址,即单指针,双指针,三指针。而引用仅具有一个/单个间接级别。2.引用不能为NULL,而指针经常设为空3.引用必须在声明时进行初始化。指针没有这种限制4.引用更安全:引用必须初始化引用一个对象,不至于有野指针之类的情况5.引用更方便:只需要在定义的时候使用&符号即可,后续的使用完全跟普通变量一样,而其底层的指针实现方式又使其相比于普通变量更方便传递6.指针更强大

2. C/C++的三种传递方式

首先,我们需要理解函数,函数就是一个执行指定任务的代码块,通常函数需要获取一些值并返回。在调用函数的时候,将函数的代码与传入参数压入栈,这里的参数(形参)是调用此函数时传入的值(实参)的拷贝副本,它在函数结束后就消失。

2.1. 值传递(call by value)

“这里的参数(形参)是调用此函数时传入的值(实参)的拷贝副本。”,这就是按值传递,基础的参数传递方式。请看如下函数片段:

int main(){
int a = 1, b = 2;
//这里的x、y就是实参
swap(a, b);


//a、b的值并不会被交换
cout << "a = " << a << endl;
cout << "b = " << b << endl;
}


void swap(int x, int y) {
//这里的x、y就是形参,是外部实参的临时副本
int temp = x;
x = y;
y = temp;
return;
}

2.2. 地址传递/指针传递 (Call by pointer or Call by address)

请看如下函数片段:

int main(){
int a = 1, b = 2;
int* pa = &a;
int* pb = &b;
//这里的pa、pb就是实参
swap(pa, pb);
//以上三行等价于下面一行
swap(&a, &b);
//a、b的值将会被交换
cout << "a = " << a << endl;
cout << "b = " << b << endl;
}


void swap(int *x, int *y) {
//这里的x、y就是形参,是外部实参(指针)的临时副本
int temp = *x;
*x = *y;
*y = temp;
return;
}

2.3. 引用传递

这是C++才有的机制,在C++中推荐使用引用传递 在上面我们讨论了引用,于是,我们同样可以非常方便使用引用来干活儿 请看如下函数片段:

int main(){
int a = 1, b = 2;


int &ra = a;
int &rb = b;
//这里的pa、pb就是实参
swap(ra, rb);
//以上三行等价于下面一行,这样就可以看出引用是多么方便
//swap(a, b);


//a、b的值将会被交换
cout << "a = " << a << endl;
cout << "b = " << b << endl;
}



void swap(int &x, int &y) {
//这里的x、y就是形参,是外部实参(引用)的临时副本
int temp = x;
x = y;
y = temp;
return;
}

3. 注意一点

4. 参考与引用

1.C/C++编程笔记:C++中的引用![2]2.What-is-the-difference-between-call-by-value-call-by-address-and-call-by-reference-in-tabular-form-under-C++[3]

References

[1] 指针常量: https://www.write-down.tech/search/指针常量
[2] C/C++编程笔记:C++中的引用!: https://www.bilibili.com/read/cv9513270
[3] What-is-the-difference-between-call-by-value-call-by-address-and-call-by-reference-in-tabular-form-under-C++: https://www.quora.com/What-is-the-difference-between-call-by-value-call-by-address-and-call-by-reference-in-tabular-form-under-C++


以上是关于C/C++浅谈引用与传递的主要内容,如果未能解决你的问题,请参考以下文章

C语言中如何将二维字符数组作为函数参数引用传递

如何在 Turbo C/C++ 中通过引用传递字符串

python numpy 和内存效率(通过引用与值传递)

C++/ASM:按值传递使用 xmm0,但通过引用使用 rdi

浅谈深拷贝和浅拷贝及几种实现方法

JS浅谈原始值与引用值操作