소년코딩

07.03 - 배열과 루프 (Array and Loop)

이전 배열 포스트에서 배열 인덱스는 상수 값이 아니어도 된다는 것을 알았다. 인덱스는 변수일 수도 있다. 즉, 루프 변수를 사용하여 배열의 모든 요소를 반복하고 일부 계산을 수행할 수 있다. 루프 변수가 차례대로 각 배열 요소에 접근하는 데 사용되는 경우 배열을 반복하는 iterating라고도 한다.

for 루프를 사용해서 배열의 모든 요소에 접근하는 예제:
int scores[] = { 84, 92, 76, 81, 56 };
const int numStudents = sizeof(scores) / sizeof(scores[0]);
int totalScore = 0;

// totalScore를 계산하기 위해 for 루프를 사용한다.
for (int student = 0; student < numStudents; ++student)
    totalScore += scores[student];

double averageScore = static_cast<double>(totalScore) / numStudents;

위 예제는 가독성과 유지 보수 측면에서 매우 훌륭하다. numStudents 변수는 배열의 요소 수다. 이 변수를 사용해서 for 루프는 배열의 모든 요소에 접근을 수행한다.

for 루프를 사용해서 배열에서 제일 높은 점수를 찾는 예제:
#include <iostream>

int main()
{
    int scores[] = { 84, 92, 76, 81, 56 };
    const int numStudents = sizeof(scores) / sizeof(scores[0]);

    int maxScore = 0; // 가장 큰 점수를 기록하는 변수
    for (int student = 0; student < numStudents; ++student)
        if (scores[student] > maxScore)
            maxScore = scores[student];

    std::cout << "The best score was " << maxScore << '\n';

    return 0;
}

위 예제에서는 maxScore 변수를 사용해서 가장 큰 점수를 기록한다. maxScore는 0으로 초기화되어 아직 점수를 보지 못했음을 나타낸다. 배열의 각 요소를 반복해서 살펴보고 이전에 보았던 것보다 높은 점수를 발견하면 maxScore를 해당 값으로 설정한다. 따라서. maxScore는 지금까지 검색한 모든 요소 중에서 항상 가장 높은 점수를 나타낸다. 배열의 검색이 끝나면 maxScore는 배열 요소들 중에서 가장 높은 점수를 나타낸다.


Mixing loops and arrays

루프는 일반적으로 다음 작업 중 하나를 수행하기 위해 배열과 함께 사용된다:

  1. 값을 계산한다. (Ex. 평균값, 합계 값)
  2. 값을 검색한다. (Ex. 최고값, 최저값)
  3. 배열을 재구성한다. (Ex. 오름차순, 내림차순)

값을 계산할 때, 변수는 일반적으로 최종값을 계산하는 데 사용되는 중간 결과를 저장하는 데 사용된다. 위의 예제에서 평균 점수를 계산할 때 totalScore는 지금까지 조사한 모든 요소의 총 점수를 보유한다.

값을 검색할 때, 변수는 일반적으로 지금까지 표시된 최상의 후보 값(또는 최적 후보의 배열 색인)을 유지하는 데 사용된다. 루프를 사용하여 가장 큰 점수를 찾는 위의 예제에서는 지금까지 찾은 가장 큰 점수를 유지하는데 maxScore이 사용된다.

배열을 정렬하는 것은 일반적으로 중첩 루프를 사용하기 때문에 조금 까다롭다. 다음 포스트에서 배열 정렬에 대해 다룰 것이다.


Arrays and off-by-one errors

배열과 루프를 함께 사용할 때 가장 까다로운 부분 중 하나는 루프가 올바른 횟수만큼 반복되는지 확인하는 것이다.

배열의 길이보다 큰 요소에 접근하려고 하면 심각한 결과를 초래할 수 있다.

int scores[] = { 84, 92, 76, 81, 56 };
const int numStudents = sizeof(scores) / sizeof(scores[0]);

int maxScore = 0; // keep track of our largest score
for (int student = 0; student <= numStudents; ++student)
    if (scores[student] > maxScore)
        maxScore = scores[student];

std::cout << "The best score was " << maxScore << '\n';

위 프로그램의 문제점은 for 루프의 조건부가 잘못되었다는 것이다! 선언된 배열은 0에서 4까지 인덱싱된 5개의 요소를 가지고 있다. 그러나 위 코드는 0에서 5 사이를 반복한다. 따라서 마지막 반복에서 배열은 다음을 실행한다.

if (scores[5] > maxScore)
    maxScore = scores[5];

그러나 scores[5]는 정의되지 않았다. 이로 인해 문제가 발생할 수 있으며, scores[5]는 쓰레기값일 될 확률이 높다. 이 경우, maxScore가 잘못될 가능성이 있다.

실수로 값을 할당하면 어떻게 되는지 상상해 보자! 다른 변수를 덮어쓸 수도 있고, 아니면 그것의 일부를 손상시킬 수도 있다. 이러한 오류는 추적하기가 매우 어렵다.

배열과 루프를 함께 사용할 때는 루프 조건을 항상 재확인하자!


cpp 번역: 이 포스트의 원문은 http://www.learncpp.com/cpp-tutorial/63-arrays-and-loops/ 입니다.

댓글 로드 중…

블로그 정보

소년코딩 - 소년코딩

소년코딩, 자바스크립트, C++, 물리, 게임 코딩 이야기

최근에 게시된 이야기