深入分析C、C++值传递、
来源:互联网 发布:伦敦金2016年历史数据 编辑:程序博客网 时间:2024/06/05 23:04
所有的函数都使用在程序运行栈(run-time stack) 中分配的存储区该存储区一直保持与该函数相关联直到函数结束为止那时存储区将自动释放以便重新使用该函数的整个存储区被称为活动记录(activation record).
系统在函数的活动记录中为函数的每个参数都提供了存储区参数的存储长度由它的型来决定参数传递是指用函数调用的实参值来初始化函数参数存储区的过程.
#include <stdio.h>
swap1(int a,int b)//按值传递
{
int temp;
temp=a;
a=b;
b=temp;
}
swap2(int *a,int* b)//按指针传递
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
/*****************************注意这两种不同的指针传递******************************/
void swap2‘’‘’‘’‘(int *a,int* b)//按指针传递
{
int *temp=NULL;
temp=a;
a=b;
b=temp;
} // 这种方法也不能交换实参的值,仅形参的值发生变化,实参不变
swap3(int &a,int& b)//按引用传递
{
int temp;
temp=a;
a=b;
b=temp;
}
void main()
{
int i1=30,i2=40;
swap1(i1,i2);
printf("a=%d,b=%d\n",i1,i2);
int a2=3,b2=4;
swap2(&a2,&b2);
printf("a=%d,b=%d\n",a2,b2);
int a3=22,b3=33;
swap3(a3,b3);
printf("a=%d,b=%d\n",a3,b3);
}
输出:
按值传递:参数传递的缺省初始化方法是把实参的值拷贝到参数的存储区中这被称为按值传递(pass-by-value).按值传递时函数不会访问当前调用的实参,函数处理的值是它本地的拷贝这些拷贝被存储在运行栈中,因此改变这些值不会影响实参的值,一旦函数结束了函数的活动记录 .将从栈中弹出,这些局部值也就消失了
在按值传递的情况下实参的内容没有被改变这意味着程序员在函数调用时无需保存和恢复实参的值.
但是按值传递并不是在所有的情况下都适合,不适合的情况包括:
1:当大型的类对象必须作为参数传递时对实际的应用程序而言分配对象并拷贝到栈中的时间和空间开销往往过大.
2:当实参的值必须被修改时,例如在函数swap()中用户想改变实参的值但是在按值传递的情况下无法做到.
// swap() 没有交换两个实参的值,仅仅是交换了形参v1,v2的值!
void swap( int v1, int v2 ) {
int tmp = v2;
v2 = v1;
v1 = tmp;
}
swap()交换实参的本地拷贝代表swap()实参的变量并没有被改变
为了获得期望的行为程序员可以使用两种方法:
一种方法是参数被声明成指针,例如swap()可重写如下
// pswap()交换v1和v2指向的值
void pswap( int *v1, int *v2 ) {
int tmp = *v2;
*v2 = *v1;
*v1 = tmp;
}
我们必须修改main()来调用pswap() 现在程序员必须传递两个对象的地址而不是对象本身
pswap( &i, &j );
修改后的程序编译运行后的结果显示了它的正确性
// 使用指针使程序员能够访问当前调用的实参
Before swap(): i: 10 j: 20
After swap(): i: 20 j: 10
第二种方法是把参数声明成引用,例如swap()可重写如下
// rswap() 交换v1和v2引用的值
void rswap( int &v1, int &v2 ) {
int tmp = v2;
v2 = v1;
v1 = tmp;
}
main()中rswap()的调用看起来像原来的swap()调用
rswap( i, j );
引用参数:把参数声明成引用,实际上改变了缺省的按值传递参数的传递机制,在按值传递时函数操纵的是实参的本地拷贝,当参数是引用时函数接收的是实参的左值而不是值的拷贝,这意味着函数知道实参在内存中的位置,因而能够改变它的值或取它的地址.
什么时候将一个参数指定为引用比较合适呢?
1:像swap()的情况,它必须将一个参数改变成指针来允许改变实参的值时就比较合适.
2:引用参数的第二种普遍用法是向主调函数返回额外的结果,
3:第三种用法是向函数传递大型类对象.
- 深入分析C、C++值传递、
- C 值传递、地址传递、引用传递
- [C]值传递、指针传递、引用传递
- C#--值传递理解
- C语言:值传递
- 【c/c++】值传递、指针传递、引用传递
- C语言函数参数传递的分析
- 参数传递深入分析
- Java值传递和引用传递及形参实参的分析(实例对比c++)
- 深入分析java值传递和引用传递?
- C/C++之深入分析inline函数
- Objective-C 对象模式深入分析
- Objective-C Method Swizzling 深入分析
- C语言 值传递与址传递
- C语言 值传递与址传递
- C语言地址传递与值传递
- 参数传递----C里面只有值传递
- C/C++值传递和引用传递
- 紫光档案-政府档案馆解决方案
- 黑马程序员------第7天笔记(包和数组)
- CentOS-6.3安装配置JDK-8
- 让MYSQL记录所有的SQL语句
- 第4周作业-数学学习工具(网络131 梁文俊)
- 深入分析C、C++值传递、
- 图像处理软件开发记录(六) 图像特效(浮雕、怀旧)
- java图片压缩
- U-boot移植出现的错误
- 求两个时间段的差在设定的范围内
- hadoop 伪分布式环境配置
- Android图形用户界面开发之ViewTree和DecorView详细介绍
- Unity 用户手册用户攻略Unity 根底学习界面工程浏览器 (Project Browser)
- 错误代码: An instance 0xc346000 of class UITableView was deallocated while key value observers were stil