변수는 일반적으로 함수 내부에 선언되어 함수 실행 중에만 존재하고 종료 후 소멸되는 지역 변수가 대부분입니다.
전역 변수
- 함수 외부에 선언된 변수를 전역 변수라고 합니다.
- 전역 변수는 프로그램 전체에서 유효하며, 모든 함수에서 접근하고 사용할 수 있습니다.
- 초기화되지 않은 전역 변수는 컴파일러에 의해 자동으로 0으로 초기화됩니다. (지역 변수는 임의의 값을 가집니다.)
- 초기화되지 않은 전역 포인터 변수는
NULL값을 갖습니다. - 전역 변수는 컴파일 시점에 결정되는 상수 값으로만 초기화할 수 있습니다.
#include <stdio.h>
int globalVar = 1; // 전역 변수 globalVar 선언 및 초기화
// int anotherGlobal = globalVar; // 컴파일 시 globalVar는 아직 미정 상태이므로 오류 발생
int main(void) {
// ...
return 0;
}
- 전역 변수의 초기화는
main함수 실행 이전에 수행됩니다. - 전역 변수 간의 직접적인 연산이나 할당은 파일 포함 시 순서 문제로 인해 예기치 않은 결과를 초래할 수 있으므로 피해야 합니다.
const키워드를 사용하여 컴파일 시점에 값이 확정된 전역 변수는 다른 전역 변수 초기화에 사용될 수 있습니다.
const int compileTimeKnownValue = 12; // 컴파일 시점에 값이 결정됨
int initializedWithConstant = compileTimeKnownValue; // 사용 가능
- 함수 내부에 전역 변수와 동일한 이름의 변수가 선언되면, 함수 내부에서는 전역 변수가 가려지고 지역 변수가 사용됩니다. 함수 범위를 벗어나면 다시 전역 변수가 유효해집니다.
정적 지역 변수 (Static Local Variable)
- 지역 변수 선언 앞에
static키워드를 붙이면 정적 지역 변수가 됩니다. - 함수 실행이 종료된 후에도
static변수는 값을 유지합니다. 다음에 해당 함수가 호출될 때 이전 값을 그대로 사용하며, 초기화는 프로그램 시작 시 단 한 번만 수행됩니다. - 정적 지역 변수는 프로그램 전체에서 유효한 생명주기를 가지지만, 접근 가능한 범위는 자신이 선언된 함수 내부로 제한됩니다.
- 메모리 상에서 전역 변수와 정적 지역 변수는 비슷한 위치에 할당되는 경향이 있습니다. (주소 값을 비교해보면 알 수 있습니다.)
전역 변수 사용 시 주의사항
- 포인터를 반환하는 함수:
- 함수 내부에서 선언된 지역 변수의 주소를 반환하는 것은 위험합니다. 해당 지역 변수는 함수 종료 후 소멸되기 때문입니다.
- 전역 변수나 정적 지역 변수의 주소를 반환하는 것은 안전합니다.
- 함수 간의 매개변수 전달이나 결과 값 반환을 위해 전역 변수를 사용하는 것을 지양해야 합니다.
- 가급적 전역 변수 사용을 최소화하는 것이 좋습니다.
- 전역 변수나 정적 지역 변수를 사용하는 함수는 스레드 환경에서 안전하지 않을 수 있습니다. (이는 고급 주제입니다.)
매크로 (Macro)
- 전처리기 지시자:
- '#'으로 시작하는 구문은 전처리기 지시자입니다.
- 전처리기 지시자는 컴파일 과정의 전처리 단계에서 처리되며, C 언어 자체의 문법 요소는 아니지만 코드 작성에 필수적입니다. (예:
#include) - 전처리기 지시자에는 세미콜론(
;)이 붙지 않습니다. #define을 사용하여 매크로를 정의합니다. 과거 C 버전에서는const대신 매크로를 상수 정의에 사용하기도 했습니다.
#define PI 3.14159- 기본 형태:
#define 매크로이름 대체문자열 - 대체문자열에는 공백, 문자열 등 다양한 형태가 올 수 있습니다.
- 매크로 정의는 컴파일 전에 텍스트 치환 방식으로 처리됩니다.
- 여러 줄에 걸친 매크로 정의는 역슬래시(
\)를 사용하여 연결합니다.
#define MULTILINE_MACRO printf("First line")\ printf("Second line") // 사용 시 MULTILINE_MACRO; 와 같이 호출됩니다.- 대체문자열이 없는 매크로도 정의할 수 있으며, 주로 조건부 컴파일에 사용됩니다.
- C 언어에는 미리 정의된 몇 가지 매크로가 있습니다.
_FILE_ // 현재 파일 이름 _LINE_ // 현재 줄 번호 _DATE_ // 현재 컴파일 날짜 _TIME_ // 현재 컴파일 시간
인자를 받는 매크로 (Parameterized Macro)
- 함수와 유사한 형태의 매크로입니다.
- 주의사항:
- 모든 사용 시 괄호로 감싸야 합니다.
- 매크로의 각 인자가 사용되는 부분은 반드시 괄호로 감싸야 합니다.
- 매크로 전체 결과 값(식)도 괄호로 감싸야 합니다.
- 여러 개의 인자를 받을 수 있습니다. (이 경우에도 각 인자는 괄호로 감싸야 합니다.)
- 매크로 호출 시 세미콜론(
;)을 붙이지 않습니다.
#define CUBE(x) ((x)*(x)*(x))
// 사용 예: printf("%d", CUBE(5));
// 실제 처리: printf("%d", ((5)*(5)*(5)));