선거일

선거일

학습 연습 문제

소개

참조

복사와 참조

지금까지 배운 내용만으로는 함수를 이용해 변수를 갱신하는 게 조금 번거로워요. 함수의 인자는 모두 복사본처럼 다뤄지기 때문에 원래 값은 바뀌지 않아요. 타입의 크기에 따라서는 이런 방식이 코드 성능에 심각한 영향을 미칠 수도 있어요.

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를 바꾸면 원래 변수에도 영향을 미쳐요. 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가 가리키는 대상을 바꾸는 것, 즉 reseating은 불가능해요. 초기화하지 않은 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위 동점은 없어요.
GitHub에서 편집 링크가 새 창이나 탭에서 열려요
C++ Exercism

선거일 문제를 시작해 볼 준비가 됐나요?

Exercism에 가입하고 C++ 트랙을 개념 19개연습 문제 100개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.