C语言中参数传递
更新时间:2023-05-12 11:33:01 阅读量: 实用文档 文档下载
C语言中参数传递
二. 参数传递
函数的形参的初始化和变量的初始化一样,如果形参具有非引用类型,则复制实参的值,如果形参为引用类型,则它是实参的别名。
1. 非引用实参
普通的非引用类型的函数通过复制对应的实参实现初始化。当用实参副本初始化形参时,函数并没有调用所传递的实参本身,因此不会修改实参的值。
注解:非引用形参表示对应实参的局部副本,对这类行参的修改仅仅改变了局部副本的值,一旦函数执行结束,这些局部变量的值也就没有了。
a. 指针形参
指针形参与其他非引用类型的行参一样,如果将新指针赋给行参,主调函数使用的实参指针的值没有改变。事实上被复制的指针只影响对指针的赋值。指针形参是const类型还是非const类型,将影响函数调用所使用的实参。
b. const行参
在调用函数时,如果该函数使用非引用的非const形参,则既给该函数传递const实参也可传递非const的实参(因为改变形参不影响const的实参,所以const实参不会被改变)。如果将形参定义为非引用的const类型,则在函数中,不可以改变实参的局部副本,由于实参是以副本的形式传递,因此传递给函数形参既可是const也可是非const对象。
注意:尽管函数的形参是const,但是编译器却将该行参声明视为普通的int型。 void fcn(const int i);
void fcn(int i);
为了兼顾C语言,认为这两种定义并不区别。
c. 复制实参的局限性
不适合复制实参的情况包括:
当需要在函数中修改实参的值时
当需要以大型对象作为实参传递时,对实际的应用而言,复制对象所付出的时间和存储空间代价往往很大。
但没有办法实习对象的复制时
对于以上几种情况,有效的办法是将形参定义为引用或指针。
2. 引用实参
与所有引用一样,引用形参直接关联到其所绑定的对象,而并非这些对象的副本。定义引
C语言中参数传递
用时,必须用与该引用绑定的对象初始化该引用。引用形参以完全相同的方式工作。每次调用函数时,引用形参被创建并与相应的实参关联。
a. 使用引用形参返回额外的信息
函数只能返回单个值,但有时候函数有不止一个的内容需要返回。这时候我们可以通过函数传递一个额外的引用实参,用于返回额外的信息。
b. 利用const引用避免复制
对于大型对象复制效率太低了,有些类型甚至无法复制,利用const引用就可以避免复制,引用形参是引用,所以不复制实参,又因为形参是const引用,所以不能使该引用来修改实参。
c. 更灵活的指向const的引用
如果函数具有普通的非const引用形参,则不能通过const对象进行调用,因为函数可以修改传来的参数,但这样就违背了实参的const特性。
int incr(int &val)
{
return ++val;
}
int main()
{
short v1=0;
const int v2=42;
int v3=incr(v1); //error, v1不是整型
v3=incr(v2); //error, v2使const对象
v3=incr(0); //error, 字面值不是左值
v3=incr(v1+v2); //error, 加法不能作为左值
int v4=incr(v3); //ok, v3是一个非const的整型值
}
问题的关键是非const引用形参只能与完全相同的非const对象关联。
最佳实践:应该将不需要修改的引用定义为const引用。普通的非const引用形参在使用时不太灵活。这样的形参既不能被const对象初始化,也不能用字面值或产生右值的表达式初始化。
C语言中参数传递
d. 传递指向指针的引用
实现两个指针的交换:
void ptrswap(int* &v1, int* &v2)
{
int* temp=v2;
v2=v1;
v1=temp;
}
行参int* &val的定义从右向左理解:v1是一个引用,与指向int型对象的指针相关联。也就是说,v1只是传递进ptrswap函数的任意指针的别名。
3. vector和其他容器类型的行参
最佳实践:通常,函数不应该有vector或其他标准容器库类型的实参。调用含有普通的非引用vector行参的函数将会复制vector的每一个元素。从避免复制vector的角度出发,应考虑将形参声明为引用类型。
4. 数组形参
a. 数组形参的定义
数组会被自动转换为指针,通常,将数组形参直接定义为指针要比数组语法更好,这样就明确的表示,函数操纵是指向数组元素的指针,而不是数组本身。
当编译器检查数组形参关联的实参时,他只会检查实参是不是指针,指针的类型和数组元素的类型是否匹配,而不会检查数组的长度。
b. 数组实参
和其他类型一样,数组形参可定义为引用或非引用类型,大部分情况下,数组以普通的非引用类型传递,此时数组会转换为指针。
最佳实践:当不需要修改数组形参的元素时,函数应该将形参的定义为指向const对象的指针。
c. 通过引用传递数组
与其他类型一样,数组形参可以声明为数组的引用,如果形参是数组的引用,编译器不会将数组实参转化为指针,而是传递数组的引用本身,在这种情况下,数组的大小成为形参和实参的一部分。编译器检查数组实参的大小与形参的大小是否匹配。
void print(int (&arr)[10]) ; //形参是一个数组的引用,数组的大小确定
C语言中参数传递
int main()
{
int i=0,j[2]={0,1};
int k[10]={0,1,2,3,4,5,6,7,8,9};
print(&i); //error,参数不是10个整型元素的数组
print(j);// error,参数不是10个整型元素的数组
print(k); //ok, 参数是10个整型元素的数组。
}
注解:&arr两本的括号是必须的,因为下标操作具有更高的优先级
f(int &arr[10]) //error,arrs是一个含有10个引用的数组
f(int (&arr)[10]) //ok, arr 是一个引用,他和一个含有10个元素的数组关联
d. 多维数组的传递
C++没有多维数组,所谓多维数组实际就是指数组的数组。除了第一维以外的所有维的长度都是元素类型的一部分。
5. 传递给函数的数组的处理
任何数组的处理程序都要保证程序停留在数组的边界内。
a. 使用标准库规范,传递指向数组的第一个元素和最后一个元素的下一个位置的指针。这中技术风格由标准库的技术启发而得。
b. 显式传递表示数组大小的形参
void print(const int ia[], size_t size);
6. main:处理命令行选项
7.含有可变形参的函数
在无法列举出传递给函数的所有实参的类型和数目时,可以使用省略符形参。省略符暂停了类型检查机制。它们的出现告诉编译器,当调用函数时,可以有0或多个实参,而实参的类型未知。
两种省略形参的形式
void foo(param_list, …);
void foo(…);
正在阅读:
C语言中参数传递05-12
《软件测试》课程设计任务书11-19
我可以输,但我绝不放弃!02-10
2017届成都市高新区九年级下学期一诊化学试卷(带解析)06-01
临床助理医师解剖学考试复习资料大全05-26
机关作风建设个人心得体会优选例文07-30
营运车辆卫星定位(GPS)、车载视频监控系使用管理规定(征求意见稿)01-17
马克思主义基本原理题库绪论10-21
美术国培心得11-30
省十一届人大五次会议06-12
- 教学能力大赛决赛获奖-教学实施报告-(完整图文版)
- 互联网+数据中心行业分析报告
- 2017上海杨浦区高三一模数学试题及答案
- 招商部差旅接待管理制度(4-25)
- 学生游玩安全注意事项
- 学生信息管理系统(文档模板供参考)
- 叉车门架有限元分析及系统设计
- 2014帮助残疾人志愿者服务情况记录
- 叶绿体中色素的提取和分离实验
- 中国食物成分表2020年最新权威完整改进版
- 推动国土资源领域生态文明建设
- 给水管道冲洗和消毒记录
- 计算机软件专业自我评价
- 高中数学必修1-5知识点归纳
- 2018-2022年中国第五代移动通信技术(5G)产业深度分析及发展前景研究报告发展趋势(目录)
- 生产车间巡查制度
- 2018版中国光热发电行业深度研究报告目录
- (通用)2019年中考数学总复习 第一章 第四节 数的开方与二次根式课件
- 2017_2018学年高中语文第二单元第4课说数课件粤教版
- 上市新药Lumateperone(卢美哌隆)合成检索总结报告
- 言中
- 传递
- 参数