C++函数基础 (一)

本文深入解析C++函数的基础知识,包括函数调用机制、参数传递方式(引用传递和拷贝传递)、函数返回类型及如何使用引用形参返回额外信息。探讨了函数声明与定义的重要性,以及如何高效利用引用形参避免不必要的拷贝。
摘要由CSDN通过智能技术生成

C++函数基础

函数的调用完成两项工作:一是用实参初始化函数对应的形参,二是将控制权转移给被调用函数,此时主调函数的执行被暂时中断,被调函数开始执行。

当遇到return语句时结束函数执行过程,一是返回return的值(有的话),二是将控制权从被调函数转移向主调函数。实参是形参的初始值,实参的类型必须与对应的形参类型相匹配(或能转化),函数有几个形参,必须提供相同数量的实参,所以形参一定会被初始化。

函数的形参列表

函数的形参列表可以为空,但是不能省略,每个形参都是含有一个声明符的声明。

int f3(int v1,v2) {/* ...*/}//错误
int f4((int v1,int v2) { }//正确

任意两个形参都不能同名,而且函数最外层作用域中的局部变量不能使用与形参一样的名字,形参名可选,但尽量加上。

函数返回类型

函数的返回类型不能是数组类型或函数类型,但可以是指向数组或函数的指针。

函数应该在头文件中声明,在源文件中定义,定义函数的源文件应该把含有函数声明的头文件包含进来。

参数传递

大致分为 引用传递 和 拷贝传递

1. 拷贝传递

一、传值参数
对变量的改动不会影响初始值,即函数对形参的所有操作都不会影响实参。

二、指针形参
指针的行为和其他非引用类型一样。当执行指针拷贝操作时,拷贝的是指针的值。拷贝之后,两个指针是不同的指针,因为指针使我们可以间接访问它所指的对象,所以通过指针可以修改它所指对象的值。

void resrt(int *p)
{
   *ip=0;
}
int i=42;
resrt(&i);
cout<<"i= "<<i<<endl;

改变 i 的值而非 i 的地址,即实参所指的对象发生了改变,但是实参本身没有发生改变。

2.传引用参数

在C++语言中,建议使用引用类型的形参代替指针。不同于拷贝传递的方式 实参的值拷贝给形参。引用形参是它对应实参的别名,引用形参将绑定到到对应的实参上。

void reset(int &i)//i是传给rese函数t对象的另一个名字
{
     i=0;
}
int j=424;
reset(j);//
cout<<"j= "<<j<<endl;

发现只需直接传入对象而无须传递对象地址

技巧:当拷贝比较大的类类型对象或者容器对象比较低效,甚至有的类类型不支持拷贝操作,应尽量避免直接拷贝他们,这时使用引用形参是比较明智选择如果函数无须改变引用形参的值,最好将其声明为常量引用。

使用引用形参返回额外信息

一个函数只能返回一个值,然而有时函数需要同时返回多个值,引用形参提供了极大便利。举个例子,我们定义一个名为find_char的函数,它返回在string对象中某个指定字符第一次出现的位置,同时还希望能返回该字符出现的总次数。
解决方案:
1.定义一种数据类型,让它包含位置和数据两个成员
2可以传入一个额外的引用实参,令其保存字符出现次数
.

#include<iostream>
#include<string>
using namespace std;
size_type find_char(const string &a,char c,size_type &occurs)
{
	auto ret=s.size();//初始假定ret为一个不可能的值 
	occurs=0;
	for(decltype(ret)i=0;i!=s.size();++i)
	{
		if(a[i]==c)
		{
			if(ret==s.size())//说明ret第一次出现 
			ret=i;//改变ret的值,以后将不会再经历这个if判断 
			++occurs;//occurs负责统计出现的总次数,隐式返回 
		}
	}
	return ret;
}

const形参和实参

当形参是const时,需注意关于顶层const的讨论,如前所述,顶层const作用于对象本身。和其他初始化过程一样,当用实参初始化形参时会忽略掉顶层const.。在重载函数时时,

void fun(const int i) {/* fun能读取i但不能向i写值 */}
void fun(int i){/*  */}//错误,重复定义了fun(int)

因为重载函数需要形参列表有明显区别。上面两个实际一样。

我们可以使用非常量初始化一个const对象,但是反过来不行。即转化原则。同时引用必须用同类型的对象,不能使用字面值,求值结果为int的表达式,需要转换的对象或者const int 类型的对象( 不能建立常量的普通引用,可建立变量的常量引用)。
另一方面,我们能传递一个字符串字面值作为find_char的第一个实参,这是因为该函数的引用形参是常量引用,而C++允许我们用字面值初始化常量引用。

尽量使用常量引用

把函数不会改变的形参定义成普通的引用是一种常见错误,这么做带给函数的调用者一种误导,即函数可以修改它实参的值,而且,使用引用而非常量引用限制了函数所能接受的实参类型,就像刚刚看到的,我们不能把const对象或者需要类型转换的对象传递给普通的引用实参。例,若我们将find_char应用改成普通引用,这样调用语句find_char(“hello woeld”,‘o’,ctr); 将发生错误。因为不能接受字面值,只能接受对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值