【C++Primer笔记】函数之参数传递

本文详细介绍了C++中函数参数传递的两种方式:传值和传引用。传值参数在函数内部操作不会影响实参,而传引用参数则允许函数直接修改实参对象。通过引用,可以避免大对象的拷贝,支持返回多个结果,并且在处理不支持拷贝的对象时更为方便。文中还给出了使用引用形参返回额外信息的示例,例如在`find_char`函数中同时返回字符出现的位置和次数。
摘要由CSDN通过智能技术生成
  1. 当形参是引用类型时, 它对应的实参被引用传递, 或者函数被传引用调用. 引用形参是它绑定的对象的别名, 也就是说, 引用形参是它对应的实参的别名
  2. 当实参的值被拷贝给形参时, 形参和实参时两个相互独立的对象. 我们说这样的实参被值传递, 或者函数被传值引用.

传值参数

  1. 此时函数对形参做的所有操作都不会影响实参.
指针形参
void reset(int *ip){
    *ip = 0;    // 改变指针ip所指对象的值.
    ip = 0;     // 只改变了ip的局部拷贝, 实参未被改变.
}
int main() {
    int i = 42;
    reset(&i);  // 改变 i 的值而非 i 的地址
    cout << "i = " << i << endl;
}

在 c++ 语言中, 建议使用引用类型的形参代替指针

传引用参数

对于引用的操作实际上是作用在引用所引的对象上.

void reset(int &i){  // i 是传给 reset 函数的对象的另一个名字
    i = 0;       // 改变了 i 所引对象的值
}

调用这一版本的 reset 函数时, 我们直接传入对象, 无需传入对象的地址.

int main() {
    int j = 42;
    reset(j);                 // 改变 i 的值而非 i 的地址
    cout << "j = " << j << endl;    //输出 j = 0
}
使用引用避免拷贝
  1. 拷贝大的类类型对象或者容器对象比较低效, 甚至有的类(包括IO类)不支持拷贝操作. 当某种类型不支持拷贝操作时, 函数只能通过引用形参访问该类型的对象.
使用引用形参返回额外信息
  1. 一个函数只能返回一个值, 而有时函数需要同时返回多个值, 引用形参为我们一次返回多个结果提供了有效的途径.

比如, 我们定义一个名为 find_char 的函数, 它返回在 string 对象中指定某个字符第一次出现的位置. 同时, 我们也希望函数能返回该字符出现的总次数.

有两种方法:

一是定义一个新的数据类型, 让它包含位置和数量两个成员
二更简单: 可以给函数传入一个额外的引用实参, 令其保存字符出现的次数. 例子如下

#include<string>
#include<iostream>
using std::string;
using namespace std;

// 返回 s 中 c 第一次出现的位置索引
// 引用形参 occurs : 负责统计 c 出现的总次数
// 已默认此单词中含有 o
string::size_type find_char(const string& s, char c,
                            string::size_type& occurs) {
    auto ret = s.size();    // 第一次出现的位置(如果有的话)
    occurs = 0;             // 设置表现出现次数的形参的值
    for (decltype(ret) i = 0; i != s.size(); ++i) { //遍历字符串 s, 找到 c 第一次出现的位置
        if (s[i] == c) {
            if (ret == s.size()) {                  // 确保只有第一次循环才会执行此 if 中的语句
                ret = i;
            }
            ++occurs;
        }
    }
    return ret;         // ret 用于返回o出现的位置, 出现次数已通过 occurs 隐式地返回
}

当我们调用 find_char 函数时, 必须传入三个实参:

  • 作为查找范围的一个 string 对象
  • 要找的字符
  • 用于保存字符出现次数的 size_type(3.2.2节 p79页 记得看看这里)
int main() {
    string s = "sht";
    string::size_type ctr;
    auto index = find_char(s, 'o', ctr);
    cout << s << "中 o 出现的次数为" << ctr << ".第一个 o 的位置为" << index << endl;
}
  • ctr 表示 o 出现的次数
  • index 指向 o 第一次出现的位置

如果 string 对象中没有 o, 则 index 等于 s.size()ctr 等于 0 .

const 形参和实参

当形参有顶层 const 时, 传给它常量对象或者非常量对象都是可以的:

void fcn(const int i){ /*fcn 能够读取 i, 但是不能向 i 写值*/ }

区别下方代码

void fcn(int i){ /*...*/ }	// 错误: 重复定义了 fcn(int)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值