传值与传引用实例(C++)


前言

对于C++语言,在调用带参数的函数时,需要进行参数传递。参数传递提供了调用函数和被调用函数交换信息的渠道。参数传递的两种方法为传值、传引用。

函数定义的一般格式为:
< 返回值类型 > < 函数名 >(< 参数列表 >)
< 函数体 >
函数定义中的参数称为形式参数,简称形参。

函数调用的一般格式为:
< 函数名 > (< 参数列表 >)
括号内是提供给被调用函数的参数,称为实在参数,简称实参。


一、传值

1.简介

C++中的参数传递一般采用的是传值(call by value)方式,即传入的只是参数的值的复制,而不是参数的地址,因此被调用函数执行时,只能访问形式参数对应的内存单元(称为形式单元,单元中存放了实在参数的值),而【不能直接访问实在参数对应的单元】,因而【无法直接改变实在参数的值】。

2.代码实例


```cpp
#include <iostream>
using namespace std;

void swap(int x,int y)		//传值
{
int temp;
temp=x;
x=y;
y=temp;
}

int main()
{
int x=10, y=20;
swap(x, y);		
//把实在参数 x 和 y 的值传给了 swap 中形式参数 x 和 y
//(注意,实参 x、y 与形参x、y 是不同的变量,都有各自不同的存储单元)
cout <<″x:<< x <<″y:<< y << endl;
return 0;
}

程序输出是:
x:10 y:20。
证明交换失败。

swap 函数中交换的也只是形参 x 和 y这两个局部变量的值,修改的是形式单元中的值,当 swap 函数执行完后,控制返回main 函数的调用语句处,继续向下执行,此时形参 x 和 y 这两个局部变量也被撤销。

可见,在整个 swap 函数执行过程中,形式参数值的改变丝毫也没影响调用函数中实在参数x 和 y 的值。

3.问题分析

从上面的程序可以看出,参数传递允许信息从调用函数流向被调用函数,而被调用函数想要将数据传给调用函数,只能通过返回结果这一途径。在许多情况下,这一限制为程序设计带来了不便,因为它使得从被调用函数向调用函数传递的信息非常有限。


二、传引用

1.简介

为了弥补传值方法的不足,使被调用的函数能够访问调用它的函数的变量,C++还提供了传引用(callby reference)这一传递参数的方式。它是把对实参变量的引用传给形式参数,即将实参变量的地址存放到对应的形参的形式单元中。

传引用方法不仅可以将数据从调用函数传递给被调用函数,也可以通过形式参数访问调用函数中的实参变量,并进行各种操作,从而实现信息从被调用函数传向调用函数。

在说明形式参数时,参数名前要加上&符号,如果没有该符号,说明该参数按照传值方式进行传递。同一函数中,允许有的参数传引用,有的参数传值。

2.代码实例

#include <iostream>
using namespace std;
void swap(int &, int &);	//(不必声明形参)

int main()
{
int x = 10, y = 20;
swap(x, y);
cout << "x:" << x << " y:" << y << endl;
return 0;
}

void swap(int & a,int & b)
{
int temp;
temp = a;
a = b;
b = temp;
}

程序输出是:
x:20 y:10。
证明交换成功。

3.问题分析

采取传引用方式,可将更多的数据从被调用函数传向调用函数。但它不是显式地修改调用程序中的变量,容易导致对变量的误修改。


三、补充

1.另一种选择(传指针的值)

#include <iostream>
using namespace std;
void swap(int *, int *);	//(不必声明形参)

int main()
{
int x = 10, y = 20;
swap(&x, &y);
cout << "x:" << x << " y:" << y << endl;
return 0;
}

void swap(int * a,int * b)
{
int temp;
temp = *a;		//此处的“ * ”符号代表取指针的值
*a = *b;		//直接修改两个指针指向的地址的值
*b = temp;
}

程序输出是:
x:20 y:10。
证明交换成功。

2.相关知识汇总

首先要明确,“引用”类型变量的声明方式:【变量类型】 & 变量名。
“指针”类型的声明方式:【基类型 *】 变量名。
所以,“指针的引用类型”应当这样声明:【基类型 *】& 变量名。

基类型 * 是指针的声明方式。

void fun(int a)    //传值,产生复制
void fun(int& a)	 //传引用,不产生复制
void fun(int* a)   //传地址,产生复制,本质上是一种传值,这个值是地址
void fun(int* a)   //传值,产生复制
void fun(int*& a)  //传引用,不产生复制
void fun(int** a)   //传地址,产生复制,本质上是一种传值,这个值是指针的地址

总结

注意两种方法的使用场合,尤其防止出现“该传引用结果传了值导致数值不能正确修改”的情况。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值