C++ 参数按数值传递和按地址传递

本文探讨了在C++中函数参数的两种传递方式:按值传递和按引用传递,并通过实例展示了如何利用按引用传递来实现对函数外部变量的修改。

参数按数值传递和按地址传递

到目前为止,我们看到的所有函数中,传递到函数中的参数全部是按数值传递的(by value)。也就是说,当我们调用一个带有参数的函数时,我们传递到函数中的是变量的数值而不是变量本身。 例如,假设我们用下面的代码调用我们的第一个函数addition :

int x=5, y=3, z;
z = addition ( x , y );

在这个例子里我们调用函数addition 同时将xy的值传给它,即分别为53,而不是两个变量:

这样,当函数addition被调用时,它的变量ab的值分别变为53,但在函数addition内对变量a 或b 所做的任何修改不会影响变量他外面的变量x 和 y 的值,因为变量xy并没有把它们自己传递给函数,而只是传递了他们的数值。

但在某些情况下你可能需要在一个函数内控制一个函数以外的变量。要实现这种操作,我们必须使用按地址传递的参数(arguments passed by reference),就象下面例子中的函数duplicate

// passing parameters by reference
#include <iostream.h>

void duplicate (int& a, int& b, int& c)
{
a*=2;
b*=2;
c*=2;
}

int main ()
{
int x=1, y=3, z=7;
duplicate (x, y, z);
cout << "x=" << x << ", y=" << y << ", z=" << z;
return 0;
}
x=2, y=6, z=14

第一个应该注意的事项是在函数duplicate的声明(declaration)中,每一个变量的类型后面跟了一个地址符ampersand sign (&),它的作用是指明变量是按地址传递的(by reference),而不是像通常一样按数值传递的(by value)。

当按地址传递(pass by reference)一个变量的时候,我们是在传递这个变量本身,我们在函数中对变量所做的任何修改将会影响到函数外面被传递的变量。

用另一种方式来说,我们已经把变量a, b,c和调用函数时使用的参数(x, y z)联系起来了,因此如果我们在函数内对a 进行操作,函数外面的x 值也会改变。同样,任何对b 的改变也会影响y,对c 的改变也会影响z>

这就是为什么上面的程序中,主程序main中的三个变量x, yz在调用函数duplicate 后打印结果显示他们的值增加了一倍。

如果在声明下面的函数:

void duplicate (int& a, int& b, int& c)

时,我们是按这样声明的:

void duplicate (int a, int b, int c)

也就是不写地址符 ampersand (&),我们也就没有将参数的地址传递给函数,而是传递了它们的值,因此,屏幕上显示的输出结果x, y ,z 的值将不会改变,仍是1,3,7

这种用地址符 ampersand (&)来声明按地址"by reference"传递参数的方式只是在C++中适用。在C 语言中,我们必须用指针(pointers)来做相同的操作。

按地址传递(Passing by reference)是一个使函数返回多个值的有效方法。例如,下面是一个函数,它可以返回第一个输入参数的前一个和后一个数值。

// more than one returning value
#include <iostream.h>
void prevnext (int x, int& prev, int& next)
{
prev = x-1;
next = x+1;
}

int main ()
{
int x=100, y, z;
prevnext (x, y, z);
cout << "Previous=" << y << ", Next=" << z;
return 0;
}

C++中,函数参数传递方式有两种常见的形式——按值传递(Pass by Value)引用传递(Pass by Reference)。这两种方式决定了函数内部如何处理外部传入的数据,并直接影响程序的行为、效率等方面。 --- ### 按值传递 (Pass by Value) #### 含义 当使用按值传递时,实际上传递的是变量的一个副本(拷贝),而不是原始数据本身。也就是说,在函数体内对该“副本”的操作不会影响到原变量。 #### 特点 1. 函数接收到的是实参的一份独立复制; 2. 修改发生在本地作用域内的新对象上; 3. 更加安全可靠但由于每次都要生成额外内存空间所以相对耗资源特别是大数据结构频繁调用场景下表现不佳。 示例代码: ```cpp void passByValue(int x){ cout << "Before change inside function:" << x << endl; x += 10; cout << "After change inside function:" << x << endl; } int main(){ int a=5; cout<<"Original value:"<<a<<endl;// Output: Original value:5 passByValue(a); cout<<"Final value after calling:"<<a<<endl; // Still prints Final value after calling:5 because original 'a' was unchanged } ``` 结果解释:尽管函数内改变了x,但主函数里的a保持不变,体现了两者之间的隔离性。 --- ### 引用传递 (Pass by Reference) #### 含义 不同于按值传递直接给予一份新的实例化版本供函数单独处置,采用引用机制则是将真正意义上的那个存储地址共享给目标区域利用起来。因此任何变动都将同步反映至源端之上。 #### 特点 1. 提高效率尤其针对较大尺寸的对象或数组而言避免多次分配释放动作节省时间成本; 2. 能够实现双向通信效果使得返回多重输出成为可能简化设计架构思路; 3. 如果不小心滥用可能导致难以追踪维护等问题需要开发者谨慎对待合理运用规则约束范围边界条件明确表达意图减少副作用发生概率。 下面的例子展示了简单的应用情形: 示例代码: ```cpp void swapValues(int &a, int &b){ int temp=a; a=b; b=temp; } int main(){ int firstNumber=10,lastNumber=20; printf("Numbers before swapping:\nFirst Number=%d\nLast Number=%d\n",firstNumber,lastNumber); swapValues(firstNumber,lastNumber); printf("\nNumbers After Swapping :\nFirst Number=%d\nLast Number=%d ",firstNumber,lastNumber); } ``` 这里我们定义了一个swapValues()方法接受两个整数类型的引用来交换他们的数值,最后可以看到确实发生了互换现象进一步验证了这一原理成立的事实情况! --- 总结来说就是当我们希望保护原始资料不受外界干扰的时候可以选择前者模式反之则推荐后者方案更有效率地完成任务需求达成目的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值