프로그래밍/C

[C언어 강좌-9] 반복문 (Loop)

Peter Ahn 2018. 5. 4. 18:30
반응형


안녕하세요 피터입니다.

오늘은 C언어의 반복문에 대해 알려드리겠습니다.


개요

반복문은 어떠한 동작을 반복적으로 수행하고자 할 때 사용합니다.
주로 처리해야 하는 데이터가 여러 개인 경우에 효율적으로 처리하기 위해서 씁니다.

순환구조를 갖기 때문에 루프(Loop)라고 부르기도 합니다.
많이 사용되는 표현 중에 영원히 순환하는 루프를 무한루프(infinite loop)라고 하는데 한자와 영어의 합성어로 재미있는 표현입니다.


루프는 대부분의 프로그램에서 필수적으로 들어가는 요소 중에 하나입니다.

일회성으로 기능하고 바로 종료되는 프로그램을 제외하면 사용자가 별도로 종료를 시키기 전까지 계속 실행되는 프로그램들이 훨씬 더 많기 때문입니다.


그러면 지금부터 C언어에서 루프가 어떤식으로 사용되는지 알려드리겠습니다.

C언어에서는 다음과 같이 크게 2가지 방식으로 루프를 구현할 수 있습니다.

바로 while for 구문입니다.

문법(Syntax)

while

기본적인 문법은 아래와 같습니다.

while(condition) 
statement;

condition이 false가 될때까지 하면 주어진 문장(statement)을 반복적으로 수행합니다.

이 때 condition이 바로 "조건절"인데 i < 10 또는 a != 5 등과 같은 부등호가 들어간 수식부터 그 결과가 True / False 가 되는 모든 식이 올 수 있습니다.


조건문을 포스팅할 때 C언어에서 0은 False이며, 0이 아닌 모든 값은 True로 해석된다고 언급드린 적이 있습니다.

따라서 조건절에는 수식뿐만 아니라 특정 값을 갖는 변수가 올 수도 있습니다.

그 결과가 True / False로 해석될 수 있기 때문입니다.


여기서 주의하셔야 할 부분이 있는데요 while 구문은 뒤에 세미콜론(;)으로 끝나는 1개의 statement만 취한다는 점입니다.

그런데 나는 여러 개의 문장을 반복적으로 수행하고 싶은데... 그러면 어떻게 해야 할까요?


C언어에서는 { } 로 감싸여진 구문은 1개의 statement로 취급합니다.

아하! 그러면 여러 개의 문장을 { } 블록으로 감싸면 되겠군요!

while(condition)
{
  statement1;
statement2;
}

이렇게 하면 여러 개의 문장을 반복적으로 수행할 수 있습니다.


주의해야 될 점이라는 것은 바로 아래와 같은 실수를 해서는 안된다는 것입니다.

while(condition);
{
  statement1;
statement2;
}

"모든 문장(statement)의 끝은 세미콜론(;)으로" 를 충실히 이행한 결과로 위와 같이 while(conditoin) 에 ; 을 붙이게 되면 대참사가 일어나게 되는 겁니다.


세미콜론 자체도 하나의 문장으로 취급되기 때문이죠. while은 세미콜론만 취하여 조건절이 만족할 때 까지 아무런 의미도 없는 ; 문장만 처리한 뒤 { } 블록의 문장들을 1번 수행하게 되겠죠.


이 것은 애초의 의도와는 전혀 다른 동작입니다.  이 모든 일이 (;) 하나 잘못 붙임으로써 발생한 일이죠.
주의해주세요!


아래는 1부터 10까지 합한 값을 출력하는 반복문입니다.
참고해주시기 바랍니다.

int i = 1;
int sum = 0;
while(i <= 10);
{
   sum += i; // sum = sum + i; 
   i++;
}
printf("Sum of 1 to 10 is %d\n", sum);


i++ 는 주석에 표시한대로 i = i + 1 의 축약표현이고,
sum += i 에서 +=는  sum = sum + i 의 축약표현입니다.

자주 사용되니 익혀두세요.


일반적으로 루프를 사용할 때에는 다음과 같은 세가지 요소가 필요합니다.

  • 초기화
  • 조건절
  • 증감연산자

위 예제에서 초기화 구문이 바로 int i = 1; int sum = 0; 에 해당됩니다.

어떠한 문장으로 반복적으로 수행하기 위해서 조건절에 들어갈 변수를 초기화해주는 부분입니다.


조건절은 아시다시피 (i <= 10)으로 풀어서 해석하자면 "i 값이 10과 같거나 작으면" 입니다.

우리가 구해야 할 값은 1부터 10까지의 합계이니 1부터 10까지 다 더하기 위해 이러한 조건절을 만든 것이죠.


반복작업이 끝나는 조건을 만족하기 위해서 필수적으로 i값이 증가하는 구문이 필요합니다.

i++; 구문이 바로 증감연산자로 이러한 역할을 수행합니다. 


for

for(initialize; condition; increasement) 
statement;

for 구문의 기본 문법은 위와 같습니다.


while과 다른 부분은 위에서 언급했던 3가지 요소를 for문 안에 넣을 수 있다는 점입니다.

위에서 보시는 바와 같이 세미콜론으로 구분하여 3요소를 구현할 수 있습니다.

이러한 장점으로 똑같이 1부터 10까지 합계를 구하는 코딩을 하면 아래처럼 좀 더 단순하게 표현할 수 있습니다.

for(int i=1; i<=10; i++)
{
   sum += i;
}
printf("Sum of 1 to 10 is %d\n", sum);


자세히 보신 분들은 눈치 채셨겠지만 이렇게 for문 내부에서 int i = 1; 과 같이 선언과 초기화를 동시에 할 수 있습니다.


다만 기억하셔야 할 부분은 { } 블록은 별도의 스택 영역에 저장되기 때문에 지금 선언된 i 변수는 for 구문의 { } 블록 내에서만 유효하다는 것입니다.


변수(Variable) 포스팅에서 Scope 기억나시죠?

아래 코드를 컴파일 해보면 i 가 undefine 되었다는 컴파일 에러를 확인하실 수 있습니다.

for(int i=1; i<=10; i++)
{
   sum += i;
}
printf("Sum of 1 to 10 is %d\n", sum);
printf("Can I access variable i(%d)?\n", i);  


do while

do
{
   statement1;   
   statement2;
}while(condition);

기본적인 문법은 while과 거의 흡사합니다.

while구문과 다른점은 루프의 조건절을 보기 전에 일단 문장을 1번 수행한다는 점입니다.

어떤 작업을 반복적으로 수행하지만, 조건에 상관없이 최소한 1번을 수행해야 될 경우에 사용하면 유용합니다.

주의하셔야 할 부분은 while(condition) 뒤에 ; 이 붙는다는 점입니다.


무한루프 (infinite loop)

조건이 항상 참(True)이어서 무한대로 수행되는 루프가 존재합니다.

위에서 언급한 무한루프인데요. 어떻게 구현할까요?

while(1)
{
   statement;
}


for(;;)
{
   statement;
}


while과 for문으로 무한루프를 구현해봤습니다.

별도로 루프를 빠져나오는 코드가 없다면 이 루프는 영원히 반복됩니다.

그렇다는 얘기는 일단 한번 시작하면 끝을 볼 수 없다는 겁니다.

하지만 대부분의 경우 의도적으로 무한루프를 구현할 때 빠져나올 구멍 한개 정도는 최소 만들어두는 편입니다.

이 때 사용되는 것이 루프 제어문입니다.


루프 제어문

break

이 구문은 루프 내부에서만 사용될 수 있으며, 루프 없이 단독으로 사용될 수는 없습니다. switch / case 구문만 예외로 하고요.

루프를 수행하다가 break 구문을 만나면 그 즉시 루프를 빠져나오게 됩니다. 마치 영화 인셉션에서 킥을 하는 것과 비슷하네요.


다음과 같이 사용하면 무한루프도 예외없이 빠져나올 수 있습니다.

int i = 1;
int sum = 0;
while(1)
{
   sum += i;

   if(i == 10)
      break;
}
printf("Sum of 1 to 10 is %d\n", sum);

자, 이렇게 하면 위에서 했던 것과 마찬가지로 1부터 10까지의 합을 무한루프를 이용해서 구현할 수 있습니다.


continue

이 구문도 break 구문과 마찬가지로 루프 제어에 사용되는 구문입니다.

루프 수행도중 이 구문을 만나면 즉시 다음 번 루프로 넘어가게 됩니다.


아래는 0부터 10까지의 수 중에 홀수만 화면에 출력하는 코드입니다.

for(int i=0; i<10; i++)
{
if(i % 2 == 0)
continue;
else
printf("%d\t", i);
}

이 때 주의하셔야 할 부분은 for문에서의 동작입니다.

while문은 증감연산자가 기본 문법(syntax)에 포함되지 않기 때문에 continue 구문을 만났을 때 바로 조건절로 넘어가게 되는데,

for문은 조건절이 아니라 증감연산자로 넘어가게 됩니다.


즉, while문은 continue구문에서 '이번 턴부터 다시 수행'이라고 한다면, for문은 '다음 턴부터 수행' 이라고 표현할 수 있겠네요.



여러분의 댓글은 저에게 크나큰 힘이 됩니다. 오류 및 의견 주시면 감사하겠습니다.

-Peter의 우아한 프로그래밍

반응형