프로그래밍C 개발자

C 언어에서 전역 변수 작업의 특징은 무엇입니까? 전역 변수를 올바르게 선언하고 사용하는 방법, 발생할 수 있는 문제와 해결 방법은 무엇입니까?

Hintsage AI 어시스턴트로 면접 통과

답변.

질문의 역사

전역 변수는 C 언어가 시작될 때부터 프로그램의 모든 함수에서 접근할 수 있는 데이터 저장 수단으로 등장했습니다. 이는 함수 매개변수를 통해 값을 명시적으로 전달하지 않고도 코드의 서로 다른 부분 간에 정보 교환을 조직할 수 있게 해줍니다. 이러한 변수들은 별도의 메모리 영역에 저장되며 프로그램의 수명 동안 존재합니다.

문제

전역 변수를 과도하게 사용하면 코드 유지 관리에 문제가 생기고, 오류 찾기가 복잡해지며, 이름 충돌의 위험이 증가합니다. 큰 프로젝트에서는 데이터가 전역적으로 변경되는 위치를 파악하기 어려워 디버깅이 어렵습니다. 또한, 여러 파일(모듈)에서 전역 변수를 잘못 선언하면 링크 오류 및 데이터 중복이 발생할 수 있습니다.

해결 방법

전역 변수를 하나의 .c 파일에 명확하게 선언하고, extern 키워드를 사용하여 그 프로토타입을 헤더 .h 파일로 분리하는 것이 모범 사례입니다. 이렇게 하면 단일 저장소가 생기고, 컴파일러가 중복을 방지합니다. 전역 변수를 최소화하기 위해 파일 범위 내에서 정적 변수를 사용합니다. 전역 상태의 과도한 사용은 함수 간에 전달되는 데이터 구조로 대체합니다.

코드 예시:

// file.h #ifndef FILE_H #define FILE_H extern int global_counter; #endif // file.c #include "file.h" int global_counter = 0; // main.c #include "file.h" #include <stdio.h> int main() { global_counter++; printf("%d\n", global_counter); return 0; }

주요 특징:

  • 전역 변수의 범위는 정의 지점에서 시작되는 전체 프로그램입니다.
  • 다른 파일에서 전역 변수에 접근하기 위해서는 extern이 필요합니다.
  • 코드의 모듈성과 가독성을 높이기 위해 전역 변수의 수를 최소화하는 것이 좋습니다.

함정 질문입니다.

전역 변수를 정적으로 선언할 수 있습니까? 그렇다면 일반 전역 변수와 어떤 차이가 있습니까?

네, static 키워드로 선언된 전역 변수는 선언된 파일 내부에서만 보입니다. 여전히 프로그램의 전체 실행 동안 존재하지만, 다른 컴파일(다른 .c 파일)에서는 접근할 수 없습니다. 이는 파일 수준에서 데이터를 캡슐화하는 데 사용됩니다.

다른 파일에서 전역 변수에 접근하기 위해 반드시 extern을 사용해야 합니까?

네, 다른 모듈에서 정의된 전역 변수에 접근하려면 반드시 extern 키워드로 선언해야 합니다(보통 헤더 파일에서). 그렇지 않으면 컴파일러가 변수를 다시 정의하는 것으로 간주할 것입니다.

// a.c int global_var = 1; // b.c extern int global_var;

다음 코드는 작동할까요?

// a.c int var; // b.c int var;

아니요, 이러한 코드는 변수 정의가 두 번 이루어져서 링크 오류를 발생시킵니다. 전역 변수의 정의는 단 하나여야 하며, 접근할 때는 extern을 사용해야 합니다.

일반 오류 및 안티 패턴

  • 서로 다른 파일에서 동일한 전역 변수의 여러 정의.
  • 함수 간 매개변수를 전달하는 대신 전역 변수를 사용하는 것.
  • 전역 상태의 과도한 사용.

실제 사례

부정적인 사례

개발자가 접근 제한 없이 전역 변수에 구성 매개변수를 배치합니다:

장점:

  • 모든 파일에서 간편하게 접근할 수 있습니다.

단점:

  • 변경의 투명성이 결여되고, 디버깅이 복잡하며, 코드를 재사용하기 어렵습니다.

긍정적인 사례

전역 변수는 단 하나의 파일에서만 정의되고, extern을 통해 접근하며 철저하게 문서화됩니다. 다른 경우에는 파일 범위의 정적 선언 또는 매개변수 구조화를 사용합니다:

장점:

  • 모듈 테스트가 용이해지고 코드 안전성이 높아집니다.

단점:

  • 데이터에 접근하기 위해 때때로 추가 래퍼를 작성해야 할 수 있습니다.