201303/while문. 심볼테이블. gerch()

2013. 4. 3. 16:51프로그래밍/C언어 TIP

◈ while문

while문의 실행 조건에 따라 변수초기화가 되어 있지 않으면, 실행 할 때 임의값을 얻게 된다. 다음 소스를 살펴보자.
키보드로부터 0을 입력 받을 때까지 정수를 읽고 그 합을 구하는 프로그램이다.

 #include <stdio.h>

int main() 

     
int number; 
     
long sum = 0; 

     
while (number != 0) 
     

           
sum = sum + number; 
           
number = number + 1; 
           
printf("Please enter an integer < 0 to quit > : "); 
           
scanf("%d",&number); 
     

     
printf("The sum of number is %ld.\n", sum); 
}

 이 소스는 정상적으로 실행은 되지만, 원하는 값을 얻지 못한다. 디버그를 통해 알아보면 
 


number의 초기화가 이루어 지지 않아 계속 임의 값이 나오는 걸 볼 수 있다. 계속 실행하다 보면 아래와 같은 그림이 나온다.

 


끝내 임의 값이 출력되는 것은 볼 수 있다. 초기화가 while문의 실행에는 큰 영향을 미친다. 
위의 소스를 수정하기 위해서는 number를 키보드로 입력 받아 초기화 하거나, 초기화를 위한값이 존재하여야 한다. 변수선언 이후에

printf("Please enter an integer <0 to quit> : ");

scanf("%d", &number);

위와 같은 명령문을 작성해주면 제어변수를 초기화 할 수 있다.

 

Watch창을 보면 number의 초기값을 1로 줬다는 것을 알 수 있다. number의 값에 의해 while문이 참이 되어 while문 안으로 진입하게 되고 0이 될 때까지 계속 입력을 받아 loop를 돌게 된다. 아래는 실행 후 정상적인 값을 출력한 결과 창이다.

 

 
◈ 심볼테이블 (SYMBOLS TABLE) 
하나의 함수가 호출될 때 필요한 메모리의 크기를 미리 계산해 둔 메모리 지도로서, 컴파일 할 때 코드 세그먼트에 생성된다. 숫자 형태로 되어 있고 함수가 호출되면 무조건 심볼 테이블의 크기에 해당하는 만큼을 프로그램 스택 메모리에 확보하게 된다. 스택에 생성된 메모리는 함수가 진행되는 동안 계속해서 사용되며 함수가 종료되면 이 메모리는 제거된다.

 컴파일러는 함수를 호출하는데 필요한 메모리의 크기를 미리 계산해 둔다. 프로그램 내에서 사용한 데이터 타입을 이용하여 함수가 호출되는데 필요한 전체 메모리 크기를 계산하게 되며, 미리 계산된 메모리 크기는 심볼 테이블에 그 정보가 저장된다.

 예를 들어

int number; 
long sum;

이라는 변수를 선언해준다. 심볼테이블을 알기 전까지는 메모리에 할당된 변수number는 number라는 글자가 색인처럼 달려 있어 CPU가 쉽게 찾아 오는 거라 생각했다. 정말 무식한 생각이다. 컴퓨터는 문자를 저장하지 않는다. 모두 숫자로 저장되기 때문에 number라는 글자도 역시 숫자의 일부로 저장되어 있을 것이다. 변수가 선언되면 심볼테이블이 만들어 진다. 메모리에서 변수는 존재하지 않지만 숫자로 된 주소는 존재한다. 컴파일러는 심볼테이블(주소)을 기반으로 컴파일 하는 것이다. CPU 역시 주소기반으로 동작한다.

 

VS C++에서 메모리에 저장된 주소를 확인하기 위해서는

 

먼저 오른쪽 수동 Watch창에 변수 앞에 &(엠퍼센트)를 붙혀준다. 옆에 보이는 숫자가 실제 변수값이 메모리에 저장되어 있는 주소이다. 자세한 내용을 파악하기 위해서는 실제 메모리에 변수가 있는지를 확인해보면 알 수 있다. 디버그 창(F5)에서 View메뉴 – Debug Windows – Memory를 클릭하면 실제 메모리의 주소창이 뜨게 된다. Alt + 6으로도 창을 띄울 수 있다.

 

<Memory의 실제 저장 주소창>

창을 우측과 아래로 늘려 바이트수와 주소를 더 많이 확인할 수 있다. 현재 창은 4byte만을 확인할 수 있도록 창이 조절되어 있다. CC CC CC CC로 되어 있는 부분은 초기화가 이루어지지 않은 임의값들이다.

 

◈ while문의 반복횟수

while문의 실행에는 반복을 종료를 결정하는 것이 중요하다. 다음 소스를 통해 알아보자.

#include <stdio.h>

int main()

{

    int number = 1;

    int sum = 0;

         while (5 > number)

   {

         sum = sum + number;

         number = number + 1;

   }

   printf("The sum of the first 5 integer is %d\n", sum);

       return 0;

}

위 소스는 1부터 5까지의 합을 구하는 프로그램이다. 하지만 while의 조건에서 5가 포함되

어 있지 않은 것을 볼 수 있다. 정확한 답을 얻기 위해서는 논리식을 바꿔주면 된다.

 while (5 >= number );

 이러한 오류를 찾기 위해 다음과 같은 소스를 작성해본다.

#include <stdio.h>

#include <conio.h> //conio는 비표준 라이브러리

 int main()

{

      int number = 1;

      int sum = 0;

              while (5 >= number)

     {

           sum = sum + number;

           printf("number : %d\nsum : %d\n", number , sum);

           number++;

           getch(); //비표준 입력으로 키보드를 누르는 순간 바로 입력된다.

     }

     printf("The sum of the first 5 integer is %d\n", sum);

           return 0;

}

VS C++에서 디버그를 해보면 프로그램의 오류 수정에서부터 어떤 변수가 어디에서 증가하는지를 알 수 있다. 크고 복잡한 프로그램일수록 프로그램의 첫 번째 코딩에서부터 주요지점에 미리 필요한 변수의 값이나 흐름을 파악할 수 잇는 출력문을 넣어두면 효과적으로 오류를 발견 할 수 있다.

 ◦ getch()

getch()함수를 사용하기 위해서는 conio.h헤더를 선언해줘야만 이 함수를 사용할 수 있습니다. conio.h는 윈도우 ms-dos기반 라이브러리라 오리지널인 conio도 일부 함수는 정상작동이 보장되지 않는다. 오래되기도 하고 호환성도 이식성도 없기 때문이다.