네 번째 강의에서, "문장, 수식, 연산자"에서는 프로그램의 흐름은 제어하게 해주는 if문에 대해서 설명했다. 그러나 여전히 프로그램을 제어하기 위해서는 단순히 참과 거짓의 결과에 따라 동작하는 if문 외에도 다른 것들이 필요할 것이다. 이 장에서는 프로그램의 흐름을 제어하기 위한 새로운 방법을 소개할 것이다.


- 간단한 배열을 사용하는 방법

- 문장을 여러 번 실행하기 위해서 for, while, do...while문을 사용하는 방법.

- 프로그램의 제어문을 종속시킬 수 있는 방법.


이 장에서는 모든 내용을 상세히 설명하지는 않겠지만, 실제로 프로그램을 작성할 수 있을 정도의 충분한 내용을 다룰 것이다.

 

1. 배열의 기초

 : for문에 대한 내용을 다루기 전에 배열에 대해서 알아보도록 하자. C에서 for문과 배열은 밀접한 관련이 있으므로 하나를 설명하지 않고 다른 하나를 소개하는 것은 힘들다. 이 장에서 설명할 for문의 예제를 이해할 수 있도록 배열에 대한 내용을 간단히 살펴보도록 하겠다.


 배열(array)은 같은 이름을 사용하지만 이름 뒤의 괄호에 나타나는 첨자(subscript)나 색인(index)에 의해서 서로 구분되는 집단적인 데이터 저장 영역의 명칭이다. 이런 개념은 배열에 대한 내용을 계속해서 접하게 되면 분명하게 이해할 수 있을 것이다. C의 다른 변수와 마찬가지로 배열을 사용하기 위해서는 먼저 선언해야 한다. 배열의 선언은 배열의 데이터형과 크기를 지정하는 것으로 가능하다. 배열의 크기는 배열 내에 포함되는 요소의 수를 뜻한다. 예를 들어, 다음 문장은 1000개의 int형 요소를 가지는 data라는 이름의 배열을 선언한다.


 int data[1000];


각각의 요소는 data[0]에서부터 data[999]까지 첨자에 의해서 지정된다. 첫 번째 요소는 data[1]이 아니라 data[0]이다. BASIC이나 다른 언어에서는 배열의 첫 번째 요소가 1이다. 그러나 C에서는 그렇지 않다. 이런 배열의 각 요소는 일반적인 정수형 변수와 동일하고, 똑같은 방법으로 사용할 수 있다. 배열의 첨자로는 다음과 같이 C의 다른 변수를 사용할 수 있다.


 int data[1000];

 int count;

 count = 100;

 data[count] = 12;    /* data[100] = 12와 동일한 문장이다. */


 지금까지 설명한 내용이 배열에 대한 기본적인 사항들이다. 이런 개념을 이해한다면 이 장에서 사용되는 예제 프로그램의 내용을 이해할 수 있을 것이다. 배열의 개념을 정확하게 이해하지 못하더라도 걱정할 필요는 없다.


2. 프로그램 실행의 제어

 : C프로그램은 기본적으로 입력된 순서대로 실행된다.프로그램은 main()함수의 처음부터 시작하여 main()의 마지막까지 문장 단위로 실행된다. 그러나 이런 실행 순서는 실제 프로그램에서 거의 나타나지 않는다. C에서는 프로그램의 실행 순서를 제어하게 해주는 다양한 프로그램 제어문이 제공된다. 앞에서는 이미 C의 가장 기본적인 제어문인 if문에 대해서 배웠으므로, 여기에서는 더욱 유용하게 사용할 수 있는 세가지 제어문에 대해서 알아보도록 하자.


2.1 for문

 : for문은 하나 이상의 블록을 지정된 횟수만큼 실행하는 C의 제어문이다. for문은 프로그램의 특정 부분을 한 번 이상 반복 실행하므로 가끔 for 순환문(for loop) 이라고도 한다. 이제 for문에 대한 상세한 내용을 알아보도록 하자. for문은 다음과 같은 구조를 가진다.


  for(initial; condition; increment)

     statement;


initial, condition, increment는 모두 C의 수식이고, statement는 C의 단일문이나 복합문이다. 프로그램이 실행되는 동안 for문을 만나게 되면 다음과 같은 동작이 수행된다.


 ① 수식 initial이 평가된다. initial은 대개 특정 값을 변수에 저장하는 할당문이다.

 ② 수식 condition이 평가된다. condition은 일반적으로 관계 수식이다.

 ③ condition이 0의 값에 해당하는 거짓으로 평가되면 for문이 종료되고 

    프로그램의 제어는 statement의 바로 다음에 잇는 문장으로 전달된다.

 ④ condition이 참으로 평가되면 statement에 포함되어 있는 C의 문장이 실행된다.

 ⑤ 수식 increment가 사용되고 나면 제어는 다시 두 번째 단계로 돌아간다.


condition이 처음에 거짓으로 평가되면 statement는 한 번도 실행되지 않는다는 것을 기억하자. 간단한 예제를 살펴보자. <리스트 6.1>에 있는 프로그램은 1부터 20까지의 수를 출력하기 위해서 for문을 사용한다. 만약 printf()문을 20번 사용한다면 여기에 나타나 있는 것보다 더욱 복잡한 프로그램이 되었을 것이다.


 /* 간단한 for문의 사용 예 */


 #include <stdio.h>


 int count;


 main()

 {

    /* 1부터 20까지의 출력 */

    for(count = 1; count <= 20; count++)

       printf("\n%d", count);

 }


-> 출력
 1
 2
 3
 ·
 ·
 ·
 19
 20

=> for문은 앞에 있는 예제와 마찬가지로 어떤 값을 증가시키며 '수를 세기 위해서' 종종 사용 된다. 또한, 값을 증가시키는 대신에 감소시키며 '수를 세기 위해' 카운터 변수를 사용할 수도 있다.

 for(count = 100; count > 0; count--)

또한, 다음 예제와 같이 1이 아닌 값을 단위로 하여 '수를 셀 수도' 있다. for(count = 0; count < 1000; count +=5) for문은 매우 융통적이다. 예를 들어, 초기화 변수의 갑이 프로그램의 앞 부분에서 이미 초기화되었다면 for문에서는 카운터 변수의 초기화를 생략할 수도 있다.

2.2 종속된 for문
 : for문은 다른 for문 내에서 사용될 수 있다. 이것을 종속된 for문의 사용이라고 한다. 종속된 for문을 사용하면 복잡한 프로그램을 간결하게 작성할 수 있다. <리스트 6.2>는 복잡한 프로그램이 아니지만 두 개의 종속된 for문이 사용되는 것을 보여준다.

<리스트 6.2> 종속된 for문

 /* 종속된 두 for문의 사용 예 */


 #include <stdio.h>


 void draw_box(int, int);


 main()

 {

    draw_box(8, 35);

    return 0;

 }


 void draw_box(int row, int column)

 {

    int col;

    for( ; row > 0; row--)

    {

       for(col = column; col > 0; col--)

          printf("x");

       printf("\n");

    }

 }


-> 출력
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

2.3 while문
 : while 순환문이라고도 하는 while문은 지정된 조건이 참이라면 계속해서 주어진 문장을 실행한다. while운은 다음과 같은 형식으로 사용된다.

  while ( condition )
       statement;

condition은 C의 수식이고, statement는 C의 단순문이나 복합문이다. 프로그램에서 while문이 사용될 때에는 다음과 같은 동작이 수행된다.

 ① 수식 condition이 평가된다.
 ② condition이 거짓(0)으로 평가되면 while문은 종료되고,
    제어는 statement 바로 다음의 문장으로 전달된다.
 ③ condition이 참으로 평가되면 statement에 포함되는 C 문장이 실행된다.
 ④ 제어는 다시 첫 번째 단계로 돌아간다.

<리스트 6.3>은 1부터 20까지의 숫자를 출력하기 위해서 while문을 사용하는 간단한 프로그램이다. 이것은 <리스트 6.1>에서 for문을 사용하여 수행한 것과 동일하다.

<리스트 6.3> while문

 /* 간단한 while문의 사용 예 */

 #include <stdio.h>


 int count;


 int main()

 {

    /* 1부너 20까지의 출력 */


    count = 1;


    while(count <= 20)

    {

       printf("\n%d", count);

       count++;

    }

    return 0;

 }


-> 출력
  1
  2
  .
  .
  20

=> 여기서 while문은 기본적으로 초기화 부분과 증감을 수행하는 부분을 포함하지 않은 for문과 동일하다는 것을 알 수 있을 것이다. 그래서 다음은

 for( ; condition; )

다음과 같이 사용할 수 있다.

 while(condition)

이런 유사성이 있으므로 for문을 사용할 수 있는 곳에서 while문을 대신 사용할 수 있는 것이다. while문을 사용할 때에는 초기화 부분에 해당하는 내용을 먼저 독립된 문장으로 포함시켜야 하고 값을 증감시키는 부분을 while문 내에 포함시켜야 한다. 대부분의 프로그래머들은 초기화 동작이나 값의 증감이 필요할 때 while문을 사용하지 않고 for문을 선호한다. 이것은 기본적으로 소스 코드를 더 이해하기 쉽기 때문이다. for문에서는 초기화 부분, 비교문, 증감 부분이 동시에 표현되므로 내용을 쉽게 알 수 있다. 그러나 while문에서는 각각의 내용이 따로 떨어져 있으므로 상대적으로 이해하기 어렵다.

2.4 종속된 while문
 : for문이나 if문과 마찬가지로 종속된 while문을 사용할 수도 있다. <리스트 6.4>는 종속된 while문의 사용 예를 보여준다. 이것이 while문을 사용하는 가장 좋은 예는 아니지만, 종속된 while문의 사용에 대한 개념을 이해할 수 있도록 도와줄 것이다.

<리스트 6.4> 종속된 while문 

 /* 종속된 while문의 사용 예 */


 #include <stdio.h>


 int array[5];


 main()

 {

    int ctr = 0, nbr = 0;


    printf("This program prompts you to enter 5 numbers\n");

    printf("Each number should be 1 to 10\n");


    while(ctr < 5)

    {

       nbr = 0;

       while(nbr < 1 || nbr > 10)

       {

          printf("\nEnter number %d of 5: ", ctr + 1);

          scanf("%d", &nbr);

       }

       array[ctr] = nbr;

       ctr++;

    }

    for(ctr = 0; ctr < 5; ctr++)

       printf("\nValue %d is %d", ctr + 1, array[ctr]);

    return 0;

 }


-> 입력/출력
 This program prompts you to enter 5 numbers
 Each number should be from 1 to 10

 Enter number 1 of 5: 3
 Enter number 2 of 5: 6
 Enter number 3 of 5: 3
 Enter number 4 of 5: 9
 Enter number 5 of 5: 2

 Value 1 is 3
 Value 2 is 6
 Value 3 is 3
 Value 4 is 9
 Value 5 is 2

2.5 do...while문
 : C의 세 번째 제어문으로는 주어진 조건이 참으로 평가되는 한 계속해서 문장이나 블록을 실행하는 do...while문이 있다. do...while 순환문은 for문이나 while문과는 달리 순환문의 처음이 아니라 마지막 부분에서 조건을 확인한다. do...while문은 다음과 같은 형식을 사용한다.

   do
      statement;
   while(condition);

condition은 C의 수식이고, statement는 C의 단순문이나 복합문이다. 프로그램에서 do...while 문이 사용될 때에는 다음과 같은 동작이 수행된다.

 ① statement의 내용이 실행된다.
 ② condition이 평가된다. 조건이 참으로 평가되면 제어는 처음으로 돌아간다.

그러나 거짓이라면 순환문은 종료된다.
do...while문에 포함된 문장은 항상 최소한 한 번 실행된다. 이것은 비교문이 순환문의 처음이 아니라 마지막 부분에서 확인되기 때문이다. 반면에 for문이나 while문은 순환문의 처음에 조건을 확인하므로, 포함된 문장은 주어진 조건이 처음부터 거짓이라면 결코 실행되지 않음. do...while문은 while문이나 for문보다 자주 사용되지 않지만, 순환문 내에 있는 문장을 최소한 한 번 실행할 필요가 있을 때 유용하다. 물론 순환문이 시작될 때 주어진 조건이 참으로 평가되게 설정하여 while문에서도 동일한 작업을 수행할 수 있을 것이다. 그러나 do...while문이 더욱 효과적일 것이다. <리스트 6.5>에는 do...while문의 사용 예가 나타나 있다.

<리스트 6.5> 간단한 do...while문

 /* 간단한 do...while문의 사용 예 */


 #include <stdio.h>


 int get_menu_choice(void);


 main()

 {

    int choice;


    choice = get_menu_choice();


    printf("You chose Menu Option %d\n", choice);


    return 0;

 }


 int get_menu_choice(void)

 {

    int selection = 0;


    do

    {

       printf("\n");

       printf("\n1 - Add a Record");

       printf("\n2 - Change a record");

       printf("\n3 - Delete a record");

       printf("\n4 - Quit");

       printf("\n");

       printf("\nEnter a selection: ");


       scanf("%d", &selection);

    }while ( selection < 1 || selection > 4 );

    return selection;

 }


3. 종속된 순환문

 : 종속된 순환문(nested loop)은 하나의 순환문 내에 다른 순환문이 표함 된 것을 말한다. 앞에서는 종속된 순환문의 몇 가지 예를 보았다. C에서는 내부의 순환문이 바깥의 독립적으로 존재해야 한다는 것을 제외하고는 종속된 순환문의 사용에 아무런 제한을 두지 않는다. 그러나 순환문을 겹쳐서 사용할 수는 없다. 다음과 같은 내용은 허용되지 않는다.


 for(count = 1; count < 100; count++)

    {

       do

       {

          /* do...while 순환문 */

    }  /* 순환문의 끈 */

       } while(x != 0);


do...while문이 완전히 for문 내에 위치된다면 아무런 문제가 발생하지 않는다.


 for(count = 1; count < 100; count++)

    {

       do

       {

          /* do...while 순환문 */

       } while(x != 0);

    }  /* 순환문의 끝 */


종속된 순환문을 사용할 때에는 내부의 순환문에서 변경된 내용이 바깥쪽의 순환문에 영향을 줄 수 있다는 사실을 기억하도록 하자. 그러나 안쪽에 있는 순환문은 바깥쪽의 순환문에서 사용되는 변수에 대해서 독립적으로 존재한다는 것을 주의하자. 이 예제에서는 이런 상황이 없다. 앞의 예제에서는 do...while문에서 count값이 변경된다면 바깥쪽의 for문이 실행되는 횟수에 영향을 주게 될 것이다. 들려 쓰기를 적용해서 문장을 정리하는 것은 종속된 순환문이 사용된 프로그램을 더욱 이해하기 쉽게 도와준다. 순환문의 각각은 바깥쪽에 있는 것보다 한단계 들여 써져야 한다. 이렇게 하면 각 순환문에 관련되어 있는 문장을 분명하게 구분할 수 있다.



'C 언어' 카테고리의 다른 글

4장 문장, 수식, 연산자  (0) 2019.06.02
5장 함수의 기본  (0) 2019.06.02
7장 입출력의 기초  (0) 2019.06.02
8장 숫자 배열 사용하기  (0) 2019.06.02
9장 포인터에 대해서  (0) 2019.06.02

+ Recent posts