学生会选举计票

概念学习C++17

简介

引用

副本与引用

按照目前学过的方式,通过函数更新原变量有些不便:按值传递的参数相当于副本,修改它不会改变原值。类型较大时,复制还可能明显影响程序性能。

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

引用可以看作别名,对引用的修改会作用到原变量。声明引用类型时使用 &。

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

引用不能重新绑定,也不能不初始化。必须使用一个已经存在的变量来初始化引用。

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

通过引用直接修改数据后,函数可能不需要再返回值。此时可以将返回类型设为 void。

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

任务说明

附近一所学校的学生会非常活跃。学生会由主席领导,每两年选举一次新主席。

今年,学校决定使用新的数字系统统计选票,需要你帮忙建立这套系统。

1. 获取 ElectionResult 中的票数

新系统需要从计票结果中取得票数。

已经为你定义了如下选举结果结构体:

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

由于结构体的所有成员都是公开的,可以使用初始化列表来初始化 ElectionResult,不必另写构造函数:

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

创建 vote_count 函数,接收 ElectionResult 的引用,返回其中的票数。

vote_count(hamilton);
// => 1804

2. 增加 ElectionResult 中的票数

终于开始处理选票了!现在需要一种方法增加 ElectionResult 中的票数。

创建返回 void 的 increment_vote_count 函数,接收 ElectionResult 的引用和一个票数,把结果中的票数增加指定数量。

ElectionResult burr{"Aaron " 1801};

increment_vote_count(burr, 3);

vote_count(burr);
// => 1804

3. 计票并确定主席

学校已收齐选票,现在需要查看结果并确定胜者。

创建 determine_result 函数,接收最终计票结果的引用,返回新主席对应 ElectionResult 的引用,并在胜者姓名前添加 "President" 前缀。最终计票结果以 std::vector<ElectionResult> 的引用传入,包含所有候选人的选举结果。

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"

为简化问题,可以假设:

  • 动态数组至少有一个元素。
  • 第一名不会出现平票。
需要一点帮助?查看分步提示

提示

通用提示

  • 即使接收的是 ElectionResult 的引用,也可以像普通对象一样使用点运算符 . 访问成员。
  • 在类型声明中使用 & 表示引用,例如 int&。
  • 如果不熟悉引用,可以阅读 Learn C++:引用。

1. 获取 ElectionResult 中的票数

  • 函数参数需要是 ElectionResult 的引用,即 ElectionResult&。
  • 可以像访问普通对象一样用 . 访问引用所指对象的成员。

2. 增加 ElectionResult 中的票数

  • 函数参数需要是 ElectionResult&。
  • 可以用点运算符 . 修改其成员变量。

3. 计票并确定主席

  • 动态数组的引用也可以像普通动态数组一样循环遍历。
  • 使用 myvector.size() 获取元素数量。