C++之值传递&指针传递&引用传递详解
2022/10/24 14:24:18
本文主要是介绍C++之值传递&指针传递&引用传递详解,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1.函数基础
一个函数由以下四部分组成:
返回类型
函数名
参数
(0个或多个)函数体
其中,函数的参数叫做形参
,函数执行的操作的语句块叫做函数体
2.值传递
像一个这样swap函数,调用的时候,会用实参
初始化swap函数对应的形参
void Swap(int a, int b) |
|
{ |
|
int tmp = a; |
|
a = b; |
|
b = tmp; |
|
} |
在内存中会拷贝一份实参的值,但是修改形参的值并不影响实参的值
- 测试用例
#include <iostream> |
|
void Swap(int a, int b) |
|
{ |
|
int tmp = a; |
|
a = b; |
|
b = tmp; |
|
} |
|
int main() |
|
{ |
|
int n = 0; |
|
int i = 1024; |
|
Swap(n, i); |
|
std::cout << "n: " << n << "\ni: " << i << std::endl; |
|
// 运行结果 |
|
// n: 0 |
|
// i: 1024 |
|
return 0; |
|
} |
int n = 0; |
|
int i = n; // i是n的值的副本 |
|
i = 42; |
3.指针传递
指针的行为和其他非引用类型一样。当执行指针拷贝操作时,拷贝的是指针的值。
拷贝之后,两个指针是不同的指针。因为指针使我们可以间接地访问它所指的对象,所以通过指针可以修改它所指对象的值
void SwapPoniter(int *a, int *b) |
|
{ |
|
int tmp = *a; |
|
*a = *b; |
|
*b = tmp; |
|
} |
- 测试用例
#include <iostream> |
|
void SwapPoniter(int *a, int *b) |
|
{ |
|
int tmp = *a; |
|
*a = *b; |
|
*b = tmp; // 修改了指针b指向的对象的值 |
|
b = 0; // 只改变了函数体中的内存拷贝,实参并没有被修改 |
|
} |
|
int main() |
|
{ |
|
int n = 0; |
|
int i = 1024; |
|
int *j = &n; |
|
int *k = &i; |
|
SwapPoniter(j, k); |
|
std::cout << "j: " << *j << "\nk: " << *k << std::endl; |
|
// 运行结果 |
|
// j: 1024 |
|
// k: 0 |
|
return 0; |
|
} |
int n = 0, i = 1024; |
|
int *p = &n, *q = &i; // p指向n;q指向i |
|
*p = 1024; // n的值被修改;p不变 |
|
p = q; // p现在指向了i;但是n与i的值都不变 |
传递指针,就是拷贝一个指针,它储存的值是一样的,解引用后是指向同一个对象,但是修改指针的值就是修改拷贝对象的值
在C语言中,大多数程序员都用得指针类型的形参去访问函数的外部对象,在C++中,建议使用引用类型的形参代替指针
4.引用传递
引用传递跟指针传递有点类似,使用引用传参,允许函数访问,改变一个或多个实参的值
void SwapQuote(int &a, int &b) |
|
{ |
|
int tmp = a; |
|
a = b; |
|
b = tmp; |
|
} |
- 测试用例
#include <iostream> |
|
void SwapQuote(int &a, int &b) |
|
{ |
|
int tmp = a; |
|
a = b; |
|
b = tmp; |
|
} |
|
int main() |
|
{ |
|
int n = 0; |
|
int i = 1024; |
|
SwapQuote(n, i); |
|
std::cout << "n: " << n << "\ni: " << i << std::endl; |
|
// 运行结果 |
|
// n: 1024 |
|
// i: 0 |
|
return 0; |
|
} |
- 使用引用传递可以避免拷贝
- 拷贝大的类类型对象或者容器对象比较低效,甚至有的类类型(包括IO类型在内)根本就不支持拷贝操作。当某种类型不支持拷贝操作时,函数只能通过引用形参访问该类型的对象。
举个例子,我们准备编写一个函数比较两个string对象的长度。因为string对象可能会非常长,所以应该尽量避免直接拷贝它们,这时使用引用形参是比较明智的选择。又因为比较长度无须改变string对象的内容,所以把形参定义成对常量的引用
- 当我们只是单纯读取实参,并不打算修改时,尽量使用常量引用
#include <iostream> |
|
void testprint(const int &a) |
|
{ |
|
std::cout << "a: " << a << std::endl; |
|
} |
|
int main() |
|
{ |
|
int num = 111; |
|
testprint(num); |
|
// 输出结果 a: 111 |
|
return 0; |
|
} |
- 使用引用传递返回额外信息
一个函数只能返回一个值,然而有时函数需要同时返回多个值,引用形参为我们一次返回多个结果提供了有效的途径
举个例子, 在刚刚的swap函数增加返回最小值与最大值
void SwapQuote(int &a, int &b, int &mix, int &max) |
|
{ |
|
int tmp = a; |
|
a = b; |
|
b = tmp; |
|
a < b ? mix = a, max = b : max = a, mix = b; |
|
} |
这样我们只需要调用的时候传入实参,即可修改实参的值
这篇关于C++之值传递&指针传递&引用传递详解的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享
- 2024-11-22ansible 的archive 参数是什么意思?-icode9专业技术文章分享
- 2024-11-22ansible 中怎么只用archive 排除某个目录?-icode9专业技术文章分享
- 2024-11-22exclude_path参数是什么作用?-icode9专业技术文章分享
- 2024-11-22微信开放平台第三方平台什么时候调用数据预拉取和数据周期性更新接口?-icode9专业技术文章分享
- 2024-11-22uniapp 实现聊天消息会话的列表功能怎么实现?-icode9专业技术文章分享
- 2024-11-22在Mac系统上将图片中的文字提取出来有哪些方法?-icode9专业技术文章分享
- 2024-11-22excel 表格中怎么固定一行显示不滚动?-icode9专业技术文章分享
- 2024-11-22怎么将 -rwxr-xr-x 修改为 drwxr-xr-x?-icode9专业技术文章分享
- 2024-11-22在Excel中怎么将小数向上取整到最接近的整数?-icode9专业技术文章分享