프로그래밍C 개발자

C 언어에서 정적 배열이 어떻게 구현되고 작동하는지 설명해 주세요. 올바르게 선언하는 방법, 동적 배열과의 차이점, 초기화 및 사용 시 주의사항은 무엇인지요?

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

답변

질문 역사

C 언어에서 배열 작업은 프로그래밍의 기본적인 측면입니다. C는 두 가지 주요 유형의 배열을 제공합니다: 정적 배열(크기가 컴파일 시점에 결정되며 스택 또는 정적/전역 저장소 영역에 할당됨)과 동적 배열(크기가 실행 시점에 결정됨). 정적 배열은 C 언어가 생성된 이래로 사용되어 왔으며 성능과 단순성을 강조합니다.

문제

정적 배열과 동적 배열의 차이를 이해하지 못하면 다음과 같은 오류에 직면할 수 있습니다: 배열 경계를 넘는 오류, 메모리 해제가 이루어지지 않음, 데이터 생명 주기 관리 오류 등. 정적 배열의 잘못된 초기화는 제거된 데이터나 초기화되지 않은 데이터의 읽기를 초래할 수 있습니다.

해결책

정적 배열의 선언은 다음과 같이 보입니다:

int arr[5] = {1, 2, 3, 4, 5};

이 경우 배열의 크기와 내용은 컴파일 시점에 결정되며, 메모리는 스택에 할당됩니다(로컬 자동 배열의 경우) 또는 정적 메모리에 할당됩니다(배열이 static으로 선언될 때나 전역 배열일 때). 부분 초기화 시 초기화되지 않은 요소는 0으로 채워진다는 점에 주목해야 합니다.

정적 배열의 크기는 프로그램 실행 중에 변경할 수 없으며, 이는 동적 배열과의 차이점입니다.

주요 특징:

  • 컴파일 시점에 결정된 변경 불가능한 크기.
  • 간단한 선언과 빠른 작업, 메모리의 보장된 해제(블록 종료 시).
  • 용이하고 안전한 초기화, 예측 가능한 메모리 관리.

질문의 함정.

1. 함수에서 정적 배열을 명시적으로 초기화하지 않으면 어떻게 되나요?

로컬 자동(static) 정적 배열은 초기화되지 않은 요소가 정의되지 않은 값을 가집니다. 그러나 배열이 static 수정자 또는 전역으로 선언되면 모든 요소는 기본적으로 0으로 초기화됩니다.

예:

void foo() { int arr1[3]; // 값이 정의되지 않음! static int arr2[3]; // 모든 요소는 0 }

2. 정적 배열을 함수에 전달하여 함수가 배열의 크기를 변경할 수 있나요?

아니요, 정적 배열의 크기는 변경할 수 없습니다 — 배열 선언 시 고정되어 있습니다. 함수는 배열의 내용으로 작업할 수 있지만 크기로는 작업할 수 없습니다.

배열을 올바르게 전달하는 예:

void processArray(int arr[], int size) { arr[0] = 42; }

3. 정적 배열 경계를 넘으면 어떻게 되나요? 실행 시간 오류가 발생하나요?

아니요, C 언어는 배열의 경계를 넘는 것을 확인하지 않습니다. 이러한 행동은 정의되지 않은 동작(ub)으로 간주되며, 이는 시스템 중단, 데이터 손상 또는 숨겨진 오류를 초래할 수 있습니다.

일반적인 실수 및 안티 패턴

  • 초기화되지 않은 로컬 자동 배열 사용.
  • 배열의 경계를 넘는 것(버퍼 오버플로우).
  • 함수에 배열 크기를 잘못 전달하기.

현실 사례

부정적인 사례

개발자는 로컬 배열을 선언하고 초기화를 잊은 후, 루프에서 사용합니다. 프로그램은 각 실행 시마다 다양한 결과를 출력하며, 때때로 읽기 단계에서 중단이 발생합니다.

장점:

  • 배열을 빠르게 선언할 수 있으며 초기화 학습에 시간을 할애하지 않음.

단점:

  • 불명확한 값으로 작업할 위험이 높고 결과 불안정성, 디버깅이 어려움.

긍정적인 사례

개발자는 배열을 명시적으로 값으로 초기화하거나 static으로 선언하여 자동으로 0으로 초기화되도록 합니다. 배열 사용 시 항상 크기와 경계를 관리합니다.

장점:

  • 프로그램의 결정적인 작동, 미정의 값 없음.

단점:

  • 크기가 미리 고정되어 있어, 큰 동적 데이터 세트에 비효율적입니다.