C

C언어를 가르칩니다.

C C언어를 가르칩니다.

for

for 문을 알아봅니다.

for

정의

for의 기본 형태는 다음과 같습니다.

for (expression;condition;expression)
    expression;

알기 쉽게 한국말로 바꾸면 다음과 같습니다.

for (/*처음에 할 것*/; /*매번 검사할 식*/; /*루프를 한번 돌고 할 것*/)
    /*루프를 돌면서 실행할 코드*/

그런데 저것만 봐서는 for이 어떻게 돌아가는지 잘 감이 오지 않습니다. 그러므로 일단 예제를 한번 실행해보고, 그것을 설명하는 그림을 보도록 합시다.

예제

int main(void)
{
    int N;
    puts("1부터 N까지 더한 값을 출력합니다. N을 입력하세요.");
    scanf("%d",&N);
    int sum=0;
    for (int i=1; i<=N; i++)
        sum+=i;
    printf("%d",sum);

    return 0;
}

10을 입력하면 결과로 55가 나옵니다. 다음은 이 코드를 분석한 그림입니다.

for문 루프
for문을 나타낸 그림

한눈에 이해가 되죠?

 

/*루프를 한번 돌고 할 것*/에는 표현식을 여러 개 넣을 수 있습니다. 쉼표로 구분합니다. 다음 예제를 봅시다.

//chicken_game.c
puts("1번 자동차와 2번 자동차가 서로를 향해 달려갑니다.\n");
int d1, d2;
for (d1=0, d2=1000; d1<=d2; d1+=50,d2-=50)
{
  printf("1번 자동차는 중앙에서 %d미터 떨어져 있습니다.\n",500-d1);
  printf("2번 자동차는 중앙에서 %d미터 떨어져 있습니다.\n",d2-500);
  printf("두 자동차 사이의 거리는 이제 %d미터밖에 남지 않았습니다.",d2-d1);
}
puts("꽝!");

실행 결과는 다음과 같습니다.

 

1번 자동차와 2번 자동차가 서로를 향해 달려갑니다.

1번 자동차는 중앙에서 500미터 떨어져 있습니다.
2번 자동차는 중앙에서 500미터 떨어져 있습니다.
두 자동차 사이의 거리는 이제 1000미터밖에 남지 않았습니다...

1번 자동차는 중앙에서 450미터 떨어져 있습니다.
2번 자동차는 중앙에서 450미터 떨어져 있습니다.
두 자동차 사이의 거리는 이제 900미터밖에 남지 않았습니다...

(중략)

1번 자동차는 중앙에서 50미터 떨어져 있습니다.
2번 자동차는 중앙에서 50미터 떨어져 있습니다.
두 자동차 사이의 거리는 이제 100미터밖에 남지 않았습니다...

1번 자동차는 중앙에서 0미터 떨어져 있습니다.
2번 자동차는 중앙에서 0미터 떨어져 있습니다.
두 자동차 사이의 거리는 이제 0미터밖에 남지 않았습니다...

꽝!

여기서 for을

for (d1=0, d2=1000; d1<=d2; d1++,--d2)

이렇게 바꾼다고 합시다. 그럼 이제 혼란이 옵니다.

"++와 --는 변수 앞에 오면 맨 처음에 실행되고, 변수 뒤에 오면 다 끝나고 실행된다면서? 그럼 먼저 d2에서 1을 빼고 그 다음에 d1에 1을 더하는 건가?"

다행히도 그런 고민을 할 필요가 없습니다. 쉼표에 도달하면 그 표현식의 실행이 끝납니다. 그러니까 d1++든 ++d1이든 간에 그냥 무조건 d1에 1을 더하는 게 먼저 실행됩니다.

 

for 중간에 조건문을 써서 좀 더 복잡한 프로그램을 만들 수 있습니다. 위에서 쓴 프로그램을 다시 봅시다.

puts("1번 자동차와 2번 자동차가 서로를 향해 달려갑니다.\n");
int d1, d2;
for (d1=0, d2=1000; d1<=d2; d1+=50,d2-=50)
{
  printf("1번 자동차는 중앙에서 %d미터 떨어져 있습니다.\n",500-d1);
  printf("2번 자동차는 중앙에서 %d미터 떨어져 있습니다.\n",d2-500);
  printf("두 자동차 사이의 거리는 이제 %d미터밖에 남지 않았습니다...\n\n",d2-d1);
}
puts("꽝!");

프로그램이 너무 단조롭습니다. 재미가 없어요. 좀 다채롭게 만들어봅시다. '이제 거리가 절반밖에 남지 않았어요! 모두 귀를 막을 준비를 하세요!'라는 말이 나오게 해서 좀 박진감 넘치게 해보자면, 이렇게 됩니다.

puts("1번 자동차와 2번 자동차가 서로를 향해 달려갑니다.\n");
int d1, d2;
for (d1=0, d2=1000; d1<=d2; d1+=50,d2-=50)
{
  printf("1번 자동차는 중앙에서 %d미터 떨어져 있습니다.\n",500-d1);
  printf("2번 자동차는 중앙에서 %d미터 떨어져 있습니다.\n",d2-500);
  if (d2-d1==500)
    puts("세상에! 이제 거리가 절반밖에 남지 않았어요! 모두 귀를 막을 준비를 하세요!");
  printf("두 자동차 사이의 거리는 이제 %d미터밖에 남지 않았습니다...\n\n",d2-d1);
}
puts("꽝!");

실행 결과는 다음과 같습니다.

(전략)

1번 자동차는 중앙에서 250미터 떨어져 있습니다.
2번 자동차는 중앙에서 250미터 떨어져 있습니다.
세상에! 이제 거리가 절반밖에 남지 않았어요! 모두 귀를 막을 준비를 하세요!
두 자동차 사이의 거리는 이제 500미터밖에 남지 않았습니다...

(후략)

자, 이제 좀 박진감 넘치네요.

break

이제 경기장 주인이 우리를 아끼고 사랑해주는 사람이라서, 우리가 귀를 막을 준비를 하지 않으면 이 치킨 게임장에서 우리를 내보낸다고 합시다. 그런데 그러려면 이 루프가 다 끝나기도 전에 나가야 합니다. 그럴 때 이런 코드를 짤 수 있습니다.

puts("1번 자동차와 2번 자동차가 서로를 향해 달려갑니다.\n");
int d1, d2;
bool notready;
for (d1=0, d2=1000; d1<=d2; d1+=50,d2-=50)
{
  printf("1번 자동차는 중앙에서 %d미터 떨어져 있습니다.\n",500-d1);
  printf("2번 자동차는 중앙에서 %d미터 떨어져 있습니다.\n",d2-500);
  if (d2-d1==500)
  {
    puts("세상에! 이제 거리가 절반밖에 남지 않았어요! 모두 귀를 막을 준비를 하세요!");
    puts("귀를 막을 준비가 되셨나요? 되셨다면 y, 안 되셨다면 n으로 답하세요.");
    char answer;
    scanf("%c",&answer);
    if (answer=='y') notready=false;
    else
    {
      notready=true;
      break;
    }
  }
  printf("두 자동차 사이의 거리는 이제 %d미터밖에 남지 않았습니다...\n\n",d2-d1);
}
if (notready) puts("당신은 귀 막을 준비를 하지 않아 경기장 밖으로 쫓겨났습니다.");
else puts("꽝!");
bool은 #include <stdbool.h>를 코드에 삽임해야 사용할 수 있는 자료형입니다.

실행 결과는 다음과 같습니다.

y로 답한 경우:

(전략)

1번 자동차는 중앙에서 250미터 떨어져 있습니다.
2번 자동차는 중앙에서 250미터 떨어져 있습니다.
세상에! 이제 거리가 절반밖에 남지 않았어요! 모두 귀를 막을 준비를 하세요!
귀를 막을 준비가 되셨나요? 되셨다면 y, 안 되셨다면 n으로 답하세요.

y

두 자동차 사이의 거리는 이제 500미터밖에 남지 않았습니다...

(후략)

y가 아닌 것으로 답한 경우:

(전략)

1번 자동차는 중앙에서 250미터 떨어져 있습니다.
2번 자동차는 중앙에서 250미터 떨어져 있습니다.
세상에! 이제 거리가 절반밖에 남지 않았어요! 모두 귀를 막을 준비를 하세요!
귀를 막을 준비가 되셨나요? 되셨다면 y, 안 되셨다면 n으로 답하세요.
u
당신은 귀 막을 준비를 하지 않아 경기장 밖으로 쫓겨났습니다.

(후략)

즉, break는 루프를 그 자리에서 끝내는 효과를 냅니다.

이 코드를 그림으로 표현하면 다음과 같습니다.

 

 continue

자, 또 마음에 안 드는 게 있습니다. 방금 작성한 코드에서 우리는 거리가 500미터밖에 남지 않았다는 것을 압니다. 그런데 y로 대답했는데도 굳이

두 자동차 사이의 거리는 이제 500미터밖에 남지 않았습니다...

를 말해줄 이유가 없습니다.  y로 답했다면 그 뒤에 있는 코드를 실행할 필요가 없습니다. 다시 말하면, 루프의 처음으로 되돌아가야 합니다. 이 경우에 우리는 이런 코드를 짤 수 있습니다.

puts("1번 자동차와 2번 자동차가 서로를 향해 달려갑니다.\n");
int d1, d2;
bool notready;
for (d1=0, d2=1000; d1<=d2; d1+=50,d2-=50)
{
  printf("1번 자동차는 중앙에서 %d미터 떨어져 있습니다.\n",500-d1);
  printf("2번 자동차는 중앙에서 %d미터 떨어져 있습니다.\n",d2-500);
  if (d2-d1==500)
  {
    puts("세상에! 이제 거리가 절반밖에 남지 않았어요! 모두 귀를 막을 준비를 하세요!");
    puts("귀를 막을 준비가 되셨나요? 되셨다면 y, 안 되셨다면 n으로 답하세요.");
    char answer;
    scanf("%c",&answer);
    if (answer=='y')
    {
      notready=false;
      continue;
    }
    else
    {
      notready=true;
      break;
    }
  }
  printf("두 자동차 사이의 거리는 이제 %d미터밖에 남지 않았습니다...\n\n",d2-d1);
}
if (notready) puts("당신은 귀 막을 준비를 하지 않아 경기장 밖으로 쫓겨났습니다.");
else puts("꽝!");

실행 결과는 다음과 같습니다.

(전략)

귀를 막을 준비가 되셨나요? 되셨다면 y, 안 되셨다면 n으로 답하세요.
y
1번 자동차는 중앙에서 200미터 떨어져 있습니다.
2번 자동차는 중앙에서 200미터 떨어져 있습니다.
두 자동차 사이의 거리는 이제 400미터밖에 남지 않았습니다...

(후략)

즉, continue는 그 뒤에 있는 코드를 다 건너뛰고 루프의 처음으로 돌아가는 효과를 냅니다. for에서 continue는 /*루프를 한번 돌고 할 것*/으로 돌아가고, while에서는 조건식으로 돌아갑니다.

댓글

댓글 본문
작성자
비밀번호
  1. 폭스킴
    예제가 재밌게 구성되어 있어서 배우기 좋아요~ ^^
버전 관리
truelight
현재 버전
선택 버전
graphittie 자세히 보기