C++/카루의 C++ 강좌

[카루의 C++ 강좌] 3-1. 반복문과 for, while, do~while

카루-R 2020. 3. 22. 11:48
반응형

드디어 재미있는 시간이 왔습니다. 이제 본격적으로 배열과 논리 연산자를 사용해 볼 겁니다.

반복문은 특정 구문을 여러 번 실행하기 위해서 사용합니다. 예를 들어 1부터 10까지 출력하는 프로그램을 만들 때,

int n{1};
std::cout << n++ << std::endl;
std::cout << n++ << std::endl;
std::cout << n++ << std::endl;
.... // 이렇게 계속 반복한다

이렇게 출력을 할 수도 있지만 일일이 타이핑을 하기가 굉장히 귀찮죠. 그리고 실수할 가능성도 있습니다.

더군다나, Ctrl+C, Ctrl+V의 힘을 빌린다고 해도 만약에 나중에 저걸 수정해야 한다면? 골치아파집니다.

오늘은 이러한 삽질(?)을 막기 위해서 반복문을 배울 겁니다. 블럭의 개념이 여기서 등장하므로 잘 살펴보세요.

 

1. for (클래식 for문)

우선 for 반복문은 아래와 같은 형태로 사용합니다.

for (초기화 식; 조건식; 증감식) {   }

조건식..? 그렇습니다! 저게 바로 bool 값을 받아들이는 조건식입니다. bool 하면 뭐다? 관계 연산자와 논리 연산자가 바로 생각이 나야 합니다. == && 이런 것들이요.

아 지금보니까 && 연산자가 r-value 레퍼런스 &&과 굉장히 닮아있네요. 아니 똑같구나;;

자, 아무튼 1부터 10까지 출력하는 프로그램을 만들어봅시다.

#include <iostream>

int main() 
{
    for (int i{1}; i <= 10; i++) 
    {
        std::cout << i << std::endl;
    }
}
1
2
3
4
5
6
7
8
9
10
for (int i{1}; i <= 10; i++) 

자, 이 부분부터 자세히 살펴보시면

int i{1}; // i 라는 변수를 선언합니다. 1로 초기화합니다.

i <= 10; // i 가 10 이하일 동안 계속 반복합니다.

i++; // 블록이 끝나면 i 의 값을 1 증가시킵니다.

즉, 위의 코드의 순서는 이렇습니다.

1. (초기화 식에서) int형 변수 i 를 선언하고 1로 초기화한다.

2. (조건식에서) i가 10 이하이므로 for 안의 내용을 실행한다.

3. i 의 값을 출력한다.

4. (증감식에서) i 의 값을 1 증가시킨다.

5. (조건식에서) i가 10 이하이므로 for 안의 내용을 실행한다.

6. i 의 값을 출력한다.

7. (증감식에서) i 의 값을 1 증가시킨다.

.

. // 이렇게 하다 i 가 10보다 커지면

.

n. (조건식에서) i 의 값이 10 초과이므로 for문을 더 이상 실행하지 않는다.

그리고 프로그램이 끝나게 됩니다. 초기화 식은 말 그대로 한 번만 실행되며 조건식과 증감식은 for문이 끝날 때 까지 실행됩니다.

다음은 1부터 100까지 더한 값을 출력해보겠습니다.

#include <iostream>

int main() 
{
    int sum{};
    for (int i{1}; i <= 100; i++) 
    {
        sum += i;
    }
    std::cout << sum;      // 5050이 출력
    return 0;
}

이 코드도 마찬가지입니다. i 를 1로 초기화하고, 100이 될 때 까지 i 의 값을 sum에 계속해서 더해줍니다.

그리고 그 결과를 출력합니다. for문 안에서 i는 1, 2, 3, 4, ...100의 값을 갖는데 그 값을 조건식이 거짓이 될 때 까지 (i > 100이면 거짓) 계속해서 sum에 더해주는겁니다.

지금까지는 i가 1이고, 1씩 증가했지만 다음처럼 사용도 가능합니다.

// i가 100부터 시작하여 1씩 감소해서 1이 될 때까지
// {100, 99, 98, 97, ...2, 1}
for (int i{100}; i >= 1; i--)

// i가 0부터 시작하여 2씩 증가하여 10이 될 때까지
// 즉, i가 10 이하의 짝수가 됨 {0, 2, 4, 6, 8, 10}
for (int i{}; i <= 10; i += 2)  

1부터 시작해서 2씩 증가시키면 1, 3, 5, 7, 9...이런 식으로 늘어나게 됩니다.

참고로, 조건식이나 초기화 식, 증감식이 필요없으면 생략해도 됩니다. 단, 세미콜론은 있어야 합니다.

for (int i{}; i < 10;) // 증감식 생략
for (; sum != 20;)     // 초기화 식, 증감식 생략
for (;;)               // 모두 생략: 조건식이 생략되면 무한 반복이 됩니다.

 

2. 범위기반 for문 (C++11)

사용자에게서 10개의 수를 입력받아 그 합을 출력하는 프로그램을 만들어볼까요?

#include <iostream>

int main()
{
    int input[10]{};
    int sum{};

    for (int i{}; i < 10; i++)
    {
        std::cin >> input[i];
    }
    for (int i{}; i < 10; i++)
    {
        sum += input[i];
    }

    std::cout << "입력 합계: " << sum;
    return 0;
}
1
3
7
5
4
9
6
4
2
6
입력 합계: 47

 

for (int i{}; i < 10; i++)
{
     std::cin >> input[i];
}

이 부분을 잘 보세요. i 의 값의 범위는 $0\ \le \ i\ <\ 10\ \left(단,\ i는정수\right)$입니다. input의 배열 크기가 10이니 배열 첨자 역시 0~9까지겠죠?

i의 값도 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}로 변하니 i를 통해 배열에 접근할 수 있는 겁니다.

즉, 위의 for문을 풀어쓰면 아래와 같습니다.

std::cin >> input[0];
std::cin >> input[1];
std::cin >> input[2];
std::cin >> input[3];
std::cin >> input[4];
std::cin >> input[5];
std::cin >> input[6];
std::cin >> input[7];
std::cin >> input[8];
std::cin >> input[9];

배열 첨자에 숫자 대신 i 를 넣고 for문을 사용하여 위의 열 줄을 단 세 줄로 줄인겁니다. 중간에 오타가 날 일도 없죠.

자 그런데, 이보다 더 편한 방법이 있습니다. 바로 범위 기반 for문입니다.

for (auto n : array)

이런 식으로 사용합니다. 여기서 auto에는 auto를 그대로 써도 되고 배열의 자료형으로 바꾸어도 됩니다.

n에는 변수 이름을 사용하고, array에는 배열의 이름을 넣으면 됩니다.

참고로 그냥 auto n이라고 쓰면 array의 요소의 값이 하나씩 n에 복사가 되고, 지난 시간에 배운 참조를 이용하면 n이 array의 각 요소에 대한 참조가 됩니다. 즉, n의 값을 변경하면 배열 array의 값이 바뀝니다.

이렇게 하면 알아서 자동으로 array에서 값을 하나씩 읽으면서 변수 n에 넘겨줍니다.

위의 예제를 범위기반 for문으로 바꾸어봅시다.

#include <iostream>

int main() {
    int input[10]{};
    int sum{};

    for (auto &n : input) // 참조를 하므로 input의 값이 변경됩니다.
    {
        std::cin >> n;
    }
    for (auto n : input) // 복사를 하므로 읽기 전용
    {
        sum += n;
    }

    std::cout << "입력 합계: " << sum;
    return 0;
}

위의 for문에선 값을 입력받아야 하므로 지난시간에 배운 참조를 통해 값을 바꾸었고, 아래의 for문에서는 읽기만 해도 되므로 복사를 통해 받았습니다. 배열과 같은 자료형에서는 범위 기반 for문을 사용하는 게 훨씬 효과적입니다.

 

while문

for문은 특정 범위의 값을 반복하기 위해 사용합니다. 1부터 100까지 더한다거나, 그런 식으로 사용을 하죠.

while문은 for문에서 초기화 식과 증감식이 빠진 형태입니다. 즉,

for ( ; var > 0 && var < 25; )
while (var > 0 && var < 25)

이 둘은 완전히 같은 의미입니다. var 변수가 0보다 크고, 그리고 25보다 작을 때 까지 반복하겠다는 뜻입니다.

즉, 0 < var < 25인 동안 계속 반복합니다. 사용법은 아시겠지만 while문의 괄호에는 조건식만 들어가고 끝납니다. 안에 세미콜론이 있으면 안 됩니다.

일반적인 for문도 while문으로 바꿀 수 있습니다.

for (int i{}; i < 10; i++) 
{
   std::cout << i;
}

위의 for문을 while문으로 나타내면 이렇습니다.

{
   int i{};
   while (i < 10) 
   {
      std::cout << i;
      i++
   }
}

참고로 가장 바깥쪽에 내포 블록을 만든 이유는, i 라는 변수는 for 문 안에서 생성되었으므로 for문이 끝나면 소멸되어야 하기 때문입니다. 이해가 안 되시면 가장 바깥쪽 중괄호는 무시하게요. 아무튼 for문의 초기화 식이 while문 위로 오고, 증감식은 while문의 가장 아래쪽으로 이동한다는 것만 알고 계시면 됩니다.

1부터 100까지 더하는 예제를 while문을 사용해서 작성하면 이렇습니다.

#include <iostream>

int main() 
{
    int sum{}, i{1};
    while (i <= 100) 
    {
        sum += i;
        i++;
    }
    std::cout << sum;      // 5050이 출력
    return 0;
}

참고로 i++; 이 후위 연산자이므로 sum += i++;이렇게 써도 정상적으로 작동합니다.

 

do~while문

 개인적으로 이건 언제 써야 하는 지 모르겠습니다.

do~while문은 while문과 비슷합니다. 하지만 차이점이 있다면 무조건 한 번은 실행한 이후에 반복을 합니다.

생김새가 조금 특이한데, 아래처럼 사용합니다.

do
{
    // 한번은 무조건 실행되는 코드
} while (조건식);

지금까지 배운 반복문과는 다르게 얘는 끝에 세미콜론이 붙습니다. 주의하세요.

보통은 무한반복이나 다른걸로 대체가 가능해서, 저는 거의 써 본적이 없습니다. 아니, 한 번도 안 썼습니다.

일단 예제를 보여드리겠습니다. 다음 예제는 '올바른 숫자'를 입력하면 종료되고, 그렇지 않으면 무한 반복하는 코드입니다.

#include <iostream>

int main()
    {
    constexpr int right_num{5};
    int input{};

    std::cout << "올바른 숫자 (0~9)를 입력하세요!\n" << std::endl;
    do
    {
        std::cout << "숫자 입력: ";
        std::cin >> input;
    } while (input != right_num);

    std::cout << "정답입니다!";
    return 0;
}
올바른 숫자 (0~9)를 입력하세요!

숫자 입력: 1
숫자 입력: 3
숫자 입력: 9
숫자 입력: 4
숫자 입력: 6
숫자 입력: 5
정답입니다!

상수 right_num에 정답인 5를 저장했습니다. 사용자에게서 계속 입력을 받고, right_num이 아니면, 즉 5가 아니면 계속해서 반복문을 실행하고, 5가 맞으면 조건식이 거짓이 되므로 탈출합니다.

 

3-1. 도전 과제

1. for문과 while문을 각각 사용해서 다음 결과를 출력하세요.

10
8
6
4
2

2. for문을 이용하여 1부터 500까지의 수 중 7의 배수의 합계를 구하세요.

 

3. for문을 사용하여 구구단 8단을 출력하는 프로그램을 만들어보세요.

// 예시
8 * 1 = 8
8 * 2 = 16
...

4. [고난이도] 범위 기반 for문을 사용하여 사용자가 10개의 실수를 입력하면 그 평균을 출력하는 프로그램을 만들어 보세요.

반응형