메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

IT/모바일

함수 정의의 포인트(1) : 변수의 수명을 이해하자

한빛미디어

|

2006-05-10

|

by HANBIT

14,206

제공: 한빛미디어 네트워크 기사

출처: 문법 떼고 다시 배우는 C 프로그래밍 Chapter 7.  함수 다루기에 익숙해지자(포인터 : 세 번째) 중에서



? 함수가 호출된 횟수를 갱신할 수 없다.
! 지속성이 있는 전역 변수 또는 static 지역 변수를 사용한다.

▒ 잘못된 소스 ▒

/* 호출한 횟수를 돌려주는 함수를 사용하는 프로그램(LocalVarBad.c) */
#include
#define MAX_COUNT 5

/* 지역 변수를 사용하는 함수 */
int getcount()
{
     /* 지역 변수를 선언, 초기화한다. */
     int count = 0;                                  

     /* 지역 변수를 증가시켜 돌려준다. */
     return ++count;
}

int main(void)
{
     int i; /* 루프 제어 변수 */

     /* getcount() 함수를 호출한다. */
     for (i = 0; i < MAX_COUNT; i++) {
          printf("%d ", getcount());
     }

     printf("n");
     return 0;
}

▶▶▶

1 1 1 1 1 ------- 매번 1이 출력된다(지역 변수). -------


문제점은 어디에 있는가?

이 프로그램은 시작될 때 함수의 호출 횟수를 카운트해서 int형 반환 값으로 돌려주는 함수를 만든 것입니다. 그런데 문제가 있군요. 어디에 문제가 있는 것일까요?

이유 : 첫 번째

①의 getcount( ) 함수 정의에서는 함수 내부에서 int형 count 지역 변수를 선언, 초기화하고 있습니다. 그리고 나서 이 함수가 불릴 때마다 count를 증가시킨 값을 함수를 호출한 곳에 돌려주고 있습니다. 문제는「지역 변수의 수명(life cycle)은 함수가 불려진 동안뿐」이라는 것입니다. 즉, 함수의 호출이 끝나면 지역 변수는 무효화됩니다.

∷ 가르침

함수를 만들 때 가장 먼저 이해해 두어야 할 것들 중의 하나는「변수의 종류와 수명의 차이」입니다. 함수 내부에서 선언한 변수는 지역 변수가 되며, 함수 외부에서 선언한 변수는 전역 변수가 됩니다.

전역 변수는 프로그램이 시작되었을 때「한 번만 초기화」되고, 그 후에 프로그램이 종료될 때까지 존속합니다. 즉, 전역 변수의 수명은「프로그램의 실행 기간」과 일치합니다. 한편 함수 내부에서 선언, 초기화된 지역 변수는 함수가「불릴 때마다 초기화」되고(초기화 코드가 있는 경우), 함수 호출 중에만 존속하며, 함수 호출이 끝나면 소멸됩니다. 이 때문에 지역 변수의 수명은「함수가 불려진 기간」뿐입니다.

그러나 지역 변수 선언 앞에 C의 static 키워드를 붙이면 지역 변수의 수명이 바뀝니다. static 지역 변수는 함수 호출이 시작될 때「단 한 번만 초기화」되고 프로그램이 종료될 때까지 존속하게 됩니다. 즉, static 지역 변수의 수명은 전역 변수의 수명과 동일한 것입니다. 다만 static 지역 변수의「통용 범위(스코프, scope)」는 일반 지역 변수와 같기 때문에 전역 변수의「통용 범위」와는 다릅니다. 전역 변수의 경우 파일이 분할되어 있는 장소에 따라서 약간 제약을 받기는 하지만 「통용 범위」는 원칙적으로 프로그램 전체입니다.

①의 문제는 이러한「지역 변수의 수명」을 잘 이해하지 못한 것이 원인입니다. 해결책으로는 2가지 방법이 있습니다. 하나는 변수 count를 다음과 같이「전역 변수」로 변경하는 것입니다(②).

     /* 전역 변수를 선언, 초기화한다. */
     int count = 0; /* 함수의 외부에서 선언, 초기화한다. */

다른 방법은 함수 내의 지역 변수 선언 앞에「static 키워드」를 붙이는 것입니다(③).

     int getcount2()
     {
     /* 함수의 static 지역 변수를 선언, 초기화한다. */
     static int count = 0; /* 함수 내에서 static을 붙여 사용한다. */
     ...;
}

「static 지역 변수」로 선언하면 초기화 코드(이 경우에는 count = 0)가 함수 시작 시에 단 한 번만 실행되며 함수를 여러 번 호출하더라도 두 번째 이후에는「초기화 코드가 실행되지 않는다」는 사실을 명심하십시오.

-------------------------------------------------------------------------
■ 정리
• 지역 변수는 함수가 불릴 때마다 초기화되며 함수 호출 중에만 존속한다.
• static 지역 변수는 함수의 최초 호출 시에 단 한 번만 초기화되며 프로그램 실행 기간 중에 계속 존속한다.
• 전역 변수는 프로그램 시작 시에 한 번만 초기화되며 프로그램의 실행 기간 중에 존속한다.
• static 키워드를 붙여도 지역 변수의 통용 범위는 동일하다(통용 범위는 함수 내부).
-------------------------------------------------------------------------

▒ 해결된 소스 ▒

/* 호출된 횟수를 돌려주는 함수를 사용하는 프로그램(LocalVarGood.c) */
#include
#define MAX_COUNT 5

/* 전역 변수를 선언, 초기화한다. */
int count = 0;                                        
/* 전역 변수 count를 사용하는 함수 */

int getcount1()
{
     /* 전역 변수를 증가시켜 돌려준다. */
     return ++count;
}
/* static 지역 변수를 사용하는 함수 */
int getcount2()
{
     /* 함수의 static 지역 변수를 선언, 초기화한다. */
     static int count = 0;                                
     /* static 지역 변수를 증가시켜 돌려준다. */
     return ++count;
}

int main(void)
{
     int i; /* 루프 제어 변수 */

     /* 전역 변수를 사용하는 getcount1() 함수를 호출한다. */
     for (i = 0; i < MAX_COUNT; i++) {
          printf("%d ", getcount1());
     }

     printf("n");

     /* static 지역 변수를 사용하는 getcount2() 함수를 호출한다. */
     for (i = 0; i < MAX_COUNT; i++) {
          printf("%d ", getcount2());
     }
    
     printf("n");
     return 0;
}

▶▶▶

1 2 3 4 5 ------- 매번 변경된다(전역 변수). -------
1 2 3 4 5 ------- 매번 변경된다(static 지역 변수). -------
TAG :
댓글 입력
자료실