저번 글에서는 조건문에 대해서 알아봤는데, 이번에는 반복문에 대해 알아보도록 하겠습니다.
반복문의 필요성
반복문은 조건문과 마찬가지로 프로그래밍 내에서 아주 중요한 역할을 합니다.
만약 여러분이 숫자를 5번 반복해서 출력해야 된다면 어떻게 해야 할까요?
간단히 생각하면 다음과 같이 할 수 있겠죠.
#include<stdio.h>
int main() {
printf("5 ");
printf("5 ");
printf("5 ");
printf("5 ");
printf("5 ");
}
나쁘지 않은 방법이고, 이렇게 해도 충분히 해결할 수 있는 문제입니다.
그런데 숫자를 100번 출력해야 한다면 어떻게 할까요?
사실 이 정도까지는 복사 붙여넣기를 통해서 쉽게 해결할 수는 있습니다.
하지만 그것이 천 번, 만 번, 1억 번이 된다면 도저히 이렇게는 할 수 없을 것입니다.
그렇기 때문에 사용하는 것이 바로 지금부터 알아볼 반복문입니다.
C언어에서 사용하는 반복문에는 for문과 while문이 있는데 먼저 for문에 대해서 설명하도록 하겠습니다.
for문
for문의 기본적인 구조는 다음과 같습니다.
for (초기화식; 조건식; 증감식) {
실행코드
}
먼저 for문의 소괄호 안을 보시면 세미콜론을 기준으로 구역이 세 구역으로 나누어진 것을 알 수 있습니다.
첫 번째 구역은 초기화 식으로 반복문에서 사용할 변수의 값을 초기화하는 부분입니다.
여기서 주의해야 할 점은 반복문 내에서 int i = 0처럼 초기화하시면 해당 변수는 해당 반복문에서만
사용할 수 있기 때문에, 이 변수는 반복문 밖에서 선언하시는 걸 권장합니다.
이 변수를 제어 변수라고 이야기합니다.
두 번째 구역에서는 조건을 설정하는데, 이곳의 조건이 True이면 반복문내의 코드를 실행합니다.
예를 들어 i < 5와 같이 조건을 설정하면, i가 5보다 작으면 반복문을 실행하는 것입니다.
세 번째 구역은 변수의 증감식을 사용하는데, 보통 증감 연산자를 사용해 변수++형식으로 사용합니다.
증감식은 i += 1처럼 사용해도 되며, 쉼표를 사용해서 복수의 변수를 제어할 수도 있습니다.
이렇게만 써놓으면 솔직히 무슨 소린지 잘 모르실 수도 있을 것 같은데요.
코드를 예시로 들면서 설명해보도록 하겠습니다.
#include<stdio.h>
int main() {
int i;
for (i = 0; i <= 5; i++) {
printf("%d\n", i);
}
}
위의 코드를 해석하면 정수형 변수 i를 0으로 초기화하고 i의 값이 5이하이면 실행코드를 수행합니다.
그리고 코드가 한번 실행될 때마다 i의 값을 1씩 증가시키는 코드입니다.
따라서 i의 값이 0, 1, 2, 3, 4, 5 순서로 6번 출력되는 것을 볼 수 있는데, 직접 해보시길 바랍니다.
왜 변수의 이름을 i로 하냐고 생각하실 수도 있는데, 이 또한 프로그래머 사이에서 암묵적인 룰입니다.
반복문에서 사용할 변수는 보통 i, j, k순서로 초기화하는데, 물론 다른 이름을 사용하셔도 됩니다.
for문을 좀 더 자세히 알아보자
이러한 기본 구조에서 생략해도 되는 경우도 존재합니다.
예를 들어 for문 이전에 i의 값을 정하여 초기화하면 for문의 초기화식을 생략해도 됩니다.(int i = 0;)
하지만 i의 값을 넣어주지 않으면 for문에서 오류가 발생하게 됩니다. (int i;)
그리고 두 번째 블록을 생략하면 조건이 무조건 True로 판단되어 반복문을 무한히 실행하게 됩니다.
세 번째 블록을 생략하면 i의 값이 바뀌지 않기 때문에 동일하게 무한 반복문이 실행됩니다.
또한 실행해야 할 코드가 한 줄이라면 중괄호를 생략하셔도 됩니다. 이는 if문과 동일합니다.
#include<stdio.h>
int main() {
int i = 0;
for (; i <= 5; i += 1) { //초기화 필요없음
printf("%d\n", i);
}
for (i = 0; ; i += 1) { //무한반복
printf("%d\n", i);
}
for (i = 0; i <= 5;) { //무한반복
printf("%d\n", i);
}
for (i = 0; i <= 5; i++) //중괄호 생략가능
printf("%d\n", i);
}
코드 내에서 //뒤에 적어놓은 내용은 주석 처리되며 컴파일러는 이를 실행하지 않습니다.
메모같은 용도라고 생각하시면 됩니다.
또한 반복문도 if문과 마찬가지로 중첩으로 사용할 수 있습니다.
대표적 예시로 구구단 프로그램이 있으니 한번 해보도록 하겠습니다.
#include<stdio.h>
int main() {
int i = 0, j = 0;
for (i = 1; i <= 9; i++) {
for (j = 1; j <= 9; j++) {
printf("%d * %d = %d | ", i, j, i * j);
}
printf("\n");
}
}
굉장히 간단한 코드인데, 이 코드는 밖에 있는 for문이 한번 실행될 때 안에 있는 for문이 9번 실행됩니다.
따라서 이 코드는 총 9 x 9 = 81번 실행됩니다. 그런데 이러면 출력이 조금 보기안좋죠?
그러면 이 코드를 조금 바꿔보겠습니다.
#include<stdio.h>
int main() {
int i = 0, j = 0;
for (i = 1; i <= 9; i++) {
for (j = 1; j <= 9; j++) {
printf("%d * %d = %2d | ", j, i, j * i);
}
printf("\n");
}
}
이러면 상당히 보기 좋게 바뀌었지 않나요? 이것이 기본적인 for반복문의 구조와 사용법입니다.
이번에는 for문을 좀 더 유연하게 사용할 수 있도록 해주는 continue와 break에 대해서 알아보겠습니다.
반복문을 제어해서 더 유연하게 사용하자
이중 break은 저번 글에서 switch를 설명할 때 말했었는데요,
반복문에서도 동일하게 사용할 수 있으며, break을 만나면 바로 반복문을 종료합니다.
그렇다면 continue는 무엇일까요? 이는 이번 실행을 생략하고 다음 실행으로 넘어가는 구문입니다.
이게 무슨 말인지는 코드를 통해서 알아보도록 하겠습니다.
#include<stdio.h>
int main() {
int i = 0;
for (i = 0; i < 5; i++) {
printf("break문사용\n");
break;
}
for (i = 0; i < 5; i++) {
printf("continue문 사용\n");
continue;
printf("사용확인");
}
}
먼저 break문 부터 보면 원래 같으면 첫 번째 for문은 5번 실행되어야 하는데 단 한 번만 실행되었습니다.
이는 break문을 만나자마자 for문을 종료하고 빠져나갔기 때문인데, 어렵지 않게 이해될 거라 생각합니다.
그렇다면 이번엔 continue를 봅시다. 결과를 보면 for문은 정상적으로 5번 실행된 것을 볼 수 있습니다.
하지만 원래는 실행되었어야 할 printf("사용확인")이 전혀 실행되지 않은 것을 볼 수 있습니다.
continue는 해당 명령이 실행되면, 뒤에 있는 코드를 전부 생략하고 다음 반복으로 넘어갑니다.
또한 for문 내에서 저번 글에 설명했던 if문을 사용할 수도 있고 그 반대도 당연히 가능합니다.
이를 통해 조건문과 반복문을 사용한 능동적으로 수행되는 프로그램을 만들 수 있는 것입니다.
while문
그렇다면 다음은 while문에 대해서 알아볼 텐데요, 일단 기본적인 구조부터 알아보도록 합시다.
while (조건식) {
실행코드
}
구조 자체는 for문보다 간단한데, for문과 다르게 초기화와 증감식을 소괄호 밖에서 해 주어야 합니다.
보통 다음과 같은 구조를 가집니다.
#include<stdio.h>
int main() {
int i = 0;
while (i <= 5) {
printf("%d ");
i++;
}
}
이렇듯 초기화는 while문 전에 해주고 증감식은 while문 내의 실행코드에서 해주는 형태를 보입니다.
용도에 따라 나눠 쓰자
이렇게만 보면 그냥 for문만 쓰면 되지 while문은 왜 쓰는 건가 하는 생각이 들 수도 있습니다.
하지만 두 반복문은 목적에 따라 구별해서 사용합니다.
보통 for문은 정해진 반복 횟수를 가진 반복문을 수행할 때 사용하고
while문은 무한 반복문이나 특정 조건을 만족할 때까지 계속해서 수행해야 할 때 사용합니다.
예를 들어 다음과 같이 사용할 수 있겠죠.
#include<stdio.h>
int main() {
int i = 0;
char ex = 'n';
while (ex == 'n') {
printf("while문 반복");
scanf("%c", &ex);
getchar();
}
}
위의 코드는 char형 변수 ex의 값이 'n'이면 계속해서 반복하고 while문의 끝에 scanf를 통해서
ex값을 변경할 수 있도록 하는 코드입니다. 그런데 코드를 보시면 getchar를 사용하고 있습니다.
이것은 입출력 글에서 설명했었는데요, 이것을 왜 사용하는지 의문일 수 있습니다.
scanf와 getchar, 입력 버퍼?
사실 이것을 사용하지 않으면 while문은 처음에 n을 입력해도 두 번째 반복에서 무조건 종료됩니다.
그 이유는 scanf가 변수에 넣을 값을 입력 버퍼로부터 하나씩 받아오기 때문입니다.
이게 어떤 이야기냐 하면, 실제로 입력 함수를 사용할 때 사용자가 값을 입력하면
그 값은 입력 버퍼에 저장되고 입력 함수는 그 값을 읽어오는 형태로 함수가 실행됩니다.
그런데 사용자가 값을 입력할 때는 사실 그 값만 입력되는 것이 아닌 개행 문자가 입력이 됩니다.
왜냐하면 값을 입력할 때 값을 입력하고 enter키를 누르기 때문이죠.
따라서 위의 while문의 처음 반복에선 우리가 입력한 값을 받아서 ex에 저장하지만
두 번째 반복에선 자동적으로 입력 버퍼에 저장되어있는 개행 문자를 읽어와서 ex에 저장합니다.
따라서 scanf는 사용자의 값을 입력받지도 않고,
ex의 값이 n이 아니기 때문에 반복문은 종료되는 현상이 발생하는 것입니다.
이런 이유로 getchar를 사용해서 입력 버퍼에 있는 개행 문자를 배출시켜줄 필요가 있습니다.
코드로 확인하시면 좀 더 직관적으로 이해하실 수 있을 것 같습니다.
#include<stdio.h>
int main() {
char c;
char d;
printf("문자를 입력해주세요. : ");
scanf("%c", &c);
printf("문자를 입력해주세요. : ");
scanf("%c", &d);
printf("c : %c, d : %c", c, d);
}
코드를 확인해보시면 scanf를 두 번 사용해서 c와 d에 문자를 입력받는데,
첫 번째 scanf에서 qwe를 입력해봅시다. 그러면 두 번째 scanf는 값을 입력받지도 않고 넘어가며,
변수 d에는 자동적으로 w가 저장되는 걸 볼 수 있습니다.
이 정도면 이 부분에 대해서는 충분히 이해가 되셨을 거라고 생각됩니다.
그리고 while문에서도 break과 continue는 for문과 동일하게 사용할 수 있습니다.
do-while
또한 while문을 사용하는 이유이자 강점이 하나 남아있는데요, 그것은 바로 do-while문입니다.
원래 while문은 조건이 일치하지 않으면 코드를 단 한 번도 실행하지 않을 수도 있는데요,
do-while문의 기본적인 구조는 while문과 같지만 최소 한 번은 while문의 실행코드를 무조건 실행합니다.
직접 코드로 확인해봅시다.
#include<stdio.h>
int main() {
int i = 0;
do {
printf("최초 한번은 무조건 이곳 실행");
} while (i != 0);
}
사용법은 do뒤의 중괄호 안에 반복문에서 수행할 코드를 입력하고, while뒤에 조건문을 넣는 형태입니다.
결과를 확인해보면 i가 0이 아닐 때 반복문을 수행하는데,
i의 값이 0임에도 불구하고 한번 실행된 것을 볼 수 있죠.
이런 do-while문은 이후에 프로그래밍할 때에도 굉장히 유용하게 사용되니 꼭 기억해두시길 바랍니다.
지금까지 C언어에서 사용되는 입출력, 조건문, 반복문 등 C언어의 기본적인 부분에 대해 알아봤습니다.
그렇다면 다음 글에선 이 세 가지를 사용해서 간단한 계산기 프로그램을 만들어보도록 하겠습니다.
감사합니다.
'프로그래밍 언어 > C언어' 카테고리의 다른 글
C언어 9. 사용자 정의 함수 (0) | 2020.07.12 |
---|---|
C언어 8. 계산기 프로그램 (0) | 2020.07.12 |
C언어 6. 조건문 (0) | 2020.07.11 |
C언어 5. 입출력 (0) | 2020.07.10 |
C언어 4. 연산자 (0) | 2020.07.10 |