59. 정적 변수

프로그래밍하다보면 전체 영역에서 사용하지 않지만 값을 유지해야 할 때가 있죠.
이럴 때는 전역 변수로 선언하면 사용하지 말아야 하는 곳에서 사용하는 실수를 범하여 버그를 만드는 원인이 되기도 한답니다.
그렇다고 지역 변수로 선언하면 함수 호출했을 때 메모리를 할당하고 끝나면 해제해서 다시 호출했을 때 이전의 값이 사라져요.

이 때 정적 변수를 선언하여 사용하면 문제를 해결할 수 있어요.
정적 변수를 선언할 때는 static 키워드를 붙여서 선언해요.
정적 변수는 특정 블록 내부에 변수를 선언해도 프로그램 시작할 때 메모리를 할당하고 해제해서 값을 유지할 수 있어요.

◈ 정적 변수와 지역 변수를 비교하는 예

#include <stdio.h>
void Foo();
int main()
{
    Foo();
    Foo();
    return 0;
}
void Foo()
{
    int i = 0;
    static int si = 0;
    i++;
    si++;
    printf("i: %d si: %d\n", i, si);
}

◈ 실행 결과

i:1 si:1
i:1 si:2

그런데 전역에 정적 변수를 선언하는 것은 어떠한 의미일까요?
전역에 정적 변수를 선언하면 같은 프로그램의 다른 소스 파일에서는 접근할 수가 없어요.
만약 같은 이름으로 다른 소스 파일에서 전역에 변수를 선언하면 두 변수는 이름은 같아도 메모리는 독립적이예요.
따라서 서로 다른 데이터를 관리할 수 있어요.

◈ 블록 외부에 정적 변수를 선언한 예

//Demo.c
#include <stdio.h>
static int si;
 
void Stub()
{
    si++;
    printf("Stub: %d\n",si);
}
//Program.c
#include <stdio.h>
static int si;
void Stub();
int main(void)
{
    si=3;
    printf("main: %d\n",si);
    Stub();
    printf("main: %d\n",si);
    si=6;
    printf("main: %d\n",si);
    Stub();
    printf("main: %d\n",si);
    return 0;
}

◈ 실행 결과

main: 3
Stub: 1
main: 3
main: 6
Stub: 2
main: 6

자세한 설명은 하지 않을게요.
위 코드를 작성해서 실행해 보고 혼자 고민해 보세요.
물론 이러한 문법을 아는 것보다는 어떨 때 이러한 변수를 선언해서 사용하는 것이 좋을 지 판단하는 능력이 더 중요해요.
여기에서는 이에 관한 설명은 생략할게요.
힌트를 주자면 srand 함수와 rand 함수 사용법을 살펴보시고 이들의 동작 원리를 고민해 보세요.
자주 사용하는 문법 사항은 아니지만 라이브러리를 만들 때 종종 사용하는 문법이예요.