핵심 정리

블록과 변수의 범위

C 언어에서 중괄호로 묶은 부분을 블록이라 부릅니다. 변수는 선언된 블록 안에서만 사용(접근)할 수 있고 블록 바깥에서는 사용(접근)할 수 없습니다. 이를 변수의 범위(scope)라고 합니다.

{
    int num1 = 10;    // 변수는 선언된 블록 안에서만 사용할 수 있음
}

지역 변수

블록 안에 선언된 변수를 지역 변수라고 부릅니다. 지역 변수는 현재 블록 안에서만 사용할 수 있습니다.

{
    int num1 = 10;    // 지역 변수
}

지역 변수는 자동 변수와 정적 변수로 선언할 수 있습니다.

{
    // 블록 안에 선언된 지역 변수
    auto int num1;      // 자동 변수
    int num2;           // 자동 변수(auto 생략)
    static int num3;    // 정적 변수
}

전역 변수

전역 변수는 함수 바깥에 선언하며 소스 파일 안의 모든 함수에서 사용할 수 있습니다(파일 범위). 전역 변수는 프로그램이 시작될 때 생성되고 값이 초기화되며 프로그램이 끝날 때 사라집니다. 또한, 전역 변수는 선언할 때 초깃값을 지정하지 않으면 0으로 초기화됩니다.

// 전역 변수 선언 및 초기화
자료형 변수이름 = 초깃값;

int main()
{

다른 소스 파일(외부)에 선언된 전역 변수를 사용하려면 extern을 사용해야 합니다(프로그램 범위). 단, extern은 외부에 전역 변수가 있다는 것을 표시만 할 뿐 전역 변수 자체를 선언하지는 않습니다.

// 다른 소스 파일에 선언된 전역 변수를 사용
extern 자료형 변수이름;

자동 변수

자동 변수는 auto를 붙여서 선언하며 보통은 auto 키워드를 생략합니다. 자동 변수는 블록이 시작될 때 생성되고 블록을 벗어나면 사라집니다. 특히 자동 변수는 초기화하지 않으면 쓰레기 값이 들어갑니다.

{
    auto int num1 = 10;    // 자동 변수. 블록이 시작될 때 생성되고 블록을 벗어나면 사라짐
    int num2 = 20;         // auto를 생략하여 자동 변수 선언
}

정적 변수

변수에 static을 붙여서 선언합니다.

void 함수()
{
    static 자료형 변수이름 = 초깃값;    // 정적 변수 선언
}

정적 변수를 지역 변수로 선언하면 함수(블록)를 벗어나도 변수가 사라지지 않습니다.

void increaseNumber()
{
    static int num1 = 0;     // 함수 안에 정적 변수를 선언하고 값을 초기화
    printf("%d\n", num1);    // 정적 변수 값 출력
    num1++;    // 정적 변수의 값을 1 증가시킴
}

int main()
{
    increaseNumber();    // 0
    increaseNumber();    // 1
    increaseNumber();    // 2
    increaseNumber();    // 3: 정적 변수가 사라지지 않고 유지되므로 값이 계속 증가함

    return 0;
}

정적 변수를 전역 변수로 선언하면 다른 소스 파일에서 extern으로 사용할 수 없습니다. 즉, 정적 전역 변수는 선언된 소스 파일 안에서만 사용할 수 있습니다(파일 범위).

// 정적 변수를 전역 변수로 선언하면 다른 소스 파일에서 extern으로 사용할 수 없음
static 자료형 변수이름;

int main()
{

정적 변수(지역, 전역)는 프로그램이 시작될 때 생성 및 초기화되고 프로그램이 끝날 때 사라집니다. 또한, 정적 변수는 선언할 때 초깃값을 지정하지 않으면 0이 들어갑니다.

정적 함수

변수를 정의할 때 앞에 static을 붙이면 정적 함수가 됩니다. 프로젝트 안에서 여러 소스 파일에 같은 이름으로 된 함수가 있으면 컴파일 에러가 발생합니다. 이때 함수를 정적 함수로 만들어주면 컴파일 에러가 발생하지 않습니다. 단, 정적 함수로 만들면 다른 소스 파일에서 사용할 수 없습니다(파일 범위).

// 정적 함수 선언하기
static 반환값자료형 함수이름()
{
}

레지스터 변수

레지스터 변수는 register를 붙여서 선언하며 메모리 대신 CPU 레지스터를 사용합니다. 일반 변수보다 속도가 빠르지만 레지스터 개수가 한정되어 있으므로 register를 붙인다고 해서 모두 레지스터를 사용하지는 않습니다. 그리고 지역 변수로만 선언할 수 있고 전역 변수로는 선언할 수 없습니다.

{
    register int num1 = 10;    // 레지스터 변수. CPU 레지스터에 생성됨
}

레지스터 변수는 레지스터에만 생성되고 메모리에는 생성되지 않으므로 주소 연산자 &를 사용할 수 없습니다. 단, 레지스터 변수에 메모리 주소는 저장할 수 있으므로 역참조 연산자 *를 사용할 수 있습니다.

지역 변수와 전역 변수의 차이점

C 언어에서 지역 변수와 전역 변수의 차이점은 다음과 같습니다.

지역 변수와 전역 변수
범위 초깃값
지역 변수 블록 자동 변수는 초기화되지 않음
정적 변수는 0
전역 변수 프로그램(정적 변수는 파일) 0

자동 변수와 정적 변수의 차이점

C 언어에서 자동 변수와 정적 변수의 차이점은 다음과 같습니다.

자동 변수와 정적 변수
수명 주기 초깃값
자동 변수 블록 시작부터 종료까지 초기화되지 않음
정적 변수 프로그램 시작부터 종료까지 0

기억 부류 지정자

C 언어에서 사용할 수 있는 기억 부류 지정자는 다음과 같습니다.

C언어 기억 부류 지정자
키워드 저장 장소 범위 초깃값 수명 주기
extern 데이터 섹션(초기화)
BSS 섹션(비초기화)
프로그램 0 프로그램 시작부터 종료까지
auto 스택 블록 초기화되지 않음 블록 시작부터 종료까지
static 데이터 섹션(초기화)
BSS 섹션(비초기화)
블록 또는 파일 0 프로그램 시작부터 종료까지
register CPU 레지스터 블록 초기화되지 않음 블록 시작부터 종료까지

실행 파일 옵션

main 함수에 argcargv를 매개변수로 지정하면 실행 파일 옵션을 가져올 수 있습니다. argc에는 실행 파일 이름을 포함한 옵션의 개수가 들어오며 argv에는 실행 파일 이름(경로), 옵션 문자열이 배열로 들어옵니다.

// argc는 옵션 개수, argv는 옵션 문자열
int main(int argc, char *argv[])