トラック
/
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のメンバーはすべてpublicなので、ElectionResultオブジェクトを初期化するためにconstructorを書く必要はありません。 代わりにinitializer listを使うことができます:

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

ElectionResultへの参照を引数として受け取り、そのElectionResultの票数を返す関数vote_countを作成しましょう。

vote_count(hamilton);
// => 1804

2. ElectionResultの票を増やす

いよいよ票を処理するときが来ました! 次は、ElectionResultの票を増やす方法が必要です。

ElectionResultへの参照と票数を引数として受け取り、そのElectionResultの票をその数だけ増やすvoid関数increment_vote_countを作成しましょう。

ElectionResult burr{"Aaron " 1801};

increment_vote_count(burr, 3);

vote_count(burr);
// => 1804

3. 開票と当選

学校は票を提出しました。いよいよ当選者を確認するときです。

最終集計への参照を受け取り、新しい会長のElectionResultへの参照を返す関数determine_resultを作成しましょう。 また、当選者の名前の先頭に"President"を付けて変更します。 最終集計は、立候補したすべての候補者のElectionResultsを要素に持つstd::vector<ElectionResult>へのreferenceとして渡されます。

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には少なくとも1つの要素があります。
  • 1位が同点になることはありません。
GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
C++ Exercism

選挙の日を始める準備はできましたか?

Exercismに登録すれば、19個のコンセプト100個の演習、そして本物の人間によるメンタリングとともに、C++を学んでマスターできます。すべて無料です。