轨道
/
C++
C++
/
练习
/
选举日
选举日

选举日

学习练习

简介

引用

拷贝与引用

以我们目前掌握的知识,借助函数来更新一个变量有点麻烦。 函数的每个实参都按拷贝处理,不会改变原来的值。 取决于你的类型有多大,这可能对代码的性能造成严重影响。

int adjust_salary(int base, int kids) {
    return base + kids * 500;
}
int now_a_mother_of_twins{2500};
adjust_salary(now_a_mother_of_twins, 2);

// now_a_mother_of_twins is still 2500
now_a_mother_of_twins = adjust_salary(now_a_mother_of_twins, 2);
// now_a_mother_of_twins is now 3500

References可以看作别名,对它们的修改会影响原来的变量。 References在类型声明中使用与号(&)。

int balance{1000};
int& budget{balance};
int pro_computer_wheels{699};
budget -= pro_computer_wheels;
// budget is now 301;
// balance is also 301;

无法重新绑定(即改变reference绑定的对象)。 不能有未初始化的reference。 References必须用一个已存在的变量来初始化。

int main_acc{1'000'000};
int side_acc{-20};
int& savings{main_acc};
// => main_acc and savings are 1'000'000

// try to reseat savings to use main account
savings = side_acc;
// savings and main_acc are now -20
// as this uses the **value** of side_acc
savings += 20;
// savings and main_acc are now 0, side_acc is still -20

int& future_budget;
// => compiler error, reference must be bound!

void

借助references的威力,你也许根本不需要让函数返回一个值。 这种情况下就用void作为返回类型。

void increase_power(int& level) {
    level += 500;
}
int goku{8700};
increase_power(goku);
// goku's power level?
// It's over 9000!

说明

你附近的一所学校有一个非常活跃的学生会。 学生会由一名会长管理,每 2 年举行一次选举,选出新会长。

在今年的选举中,大家决定需要一套新的数字系统来计票。学校需要你帮忙搭建这套新系统。

1. 从ElectionResult获取票数

新系统需要一种从计数器获取票数的方式。

选举结果结构体已经为你创建好了,它的定义如下:

struct ElectionResult {
    // Name of the candidate
    std::string name{};
    // Number of votes the candidate has
    int votes{};
};

由于struct中的所有成员都是公有的,你不需要编写constructor来初始化ElectionResult对象。 你可以改用initializer list:

ElectionResult hamilton{"Alex", 1804};
// => the hamilton object was initialized with the name "Alex" and 1804 votes.

创建一个函数vote_count,它接受一个ElectionResult的引用作为实参,并返回该ElectionResult中的票数。

vote_count(hamilton);
// => 1804

2. 增加ElectionResult的票数

终于到了处理选票的时候了! 现在你需要一种增加ElectionResult中票数的方式。

创建一个void函数increment_vote_count,它接受一个ElectionResult的引用以及要增加的票数,并将该ElectionResult增加相应的票数。

ElectionResult burr{"Aaron " 1801};

increment_vote_count(burr, 3);

vote_count(burr);
// => 1804

3. 计票与会长职位

学校已经提交了他们的选票,现在是时候检查结果,找出获胜者了。

创建一个函数determine_result,它接收最终计票结果的引用,并返回新会长的ElectionResult的引用。 它还应该通过在获胜者姓名前加上“President”来修改获胜者的姓名。 最终计票结果以reference的形式给出,指向std::vector<ElectionResult>,这是一个包含所有参选候选人的ElectionResults的向量。

ElectionResult sanchez{"Pedro", 471};
ElectionResult wheatley{"Summer", 340};
std::vector<ElectionResult> final_count{sanchez, wheatley};

ElectionResult& winner = determine_result(final_count);

winner.name;
// => "President Pedro"

为了简单起见,你可以假设:

  • vector中至少有一个元素。
  • 第一名不会出现平局。
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
C++ Exercism

准备好开始 选举日 了吗?

注册 Exercism,借助 19 个概念100 个练习 和真人导师指导,学习并掌握 C++,全部免费。