프로그래밍C 소프트웨어 개발자

C에서 구조체 초기화는 어떻게 이루어지나요? 다양한 초기화 방법, 필드 초기화 순서, 부분 초기화 및 중첩 구조체 사용 시 발생할 수 있는 문제에 대해 설명해 주세요.

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

답변

C에서는 구조체를 초기화하는 몇 가지 방법이 있습니다:

  1. 표준 초기화 (순서 기반):
struct Point { int x, y; }; struct Point p = {10, 20};

필드는 선언된 순서대로 초기화됩니다.

  1. 이름 있는 필드 초기화 (C99+):
struct Point p = {.y = 20, .x = 10};

필드를 임의의 순서로 초기화할 수 있습니다.

  1. 부분 초기화: 모든 필드를 명시하지 않으면 나머지 필드는 자동으로 0으로 초기화됩니다.
struct Rect { int x, y, w, h; } r = {1, 2}; // w와 h는 0
  1. 중첩 구조체: 중첩 구조체를 초기화하려면 모든 중첩 값을 순차적으로 (또는 이름을 사용하여) 지정해야 합니다.
struct Color { int r, g, b; }; struct Pixel { struct Point pos; struct Color col; }; struct Pixel px = {{10,20}, {255,0,0}};

이름 있는 초기화는 오류를 피하는 데 도움이 됩니다:

struct Pixel px = {.col = {.r = 255, .g = 0, .b = 0}};

주의 사항:

  • 순서 기반 초기화 시 필드 순서에서 실수를 하기 쉽습니다.
  • 부분 초기화는 중첩 포인터가 포함된 구조체에 대해 항상 안전하지 않습니다. 이 경우 초기화되지 않은 포인터는 명시적으로 초기화하지 않으면 NULL이 되지 않으며, 구조체가 정적/전역 스코프를 갖는 경우에만 그렇습니다.
  • 형식이 변경되면 (예: 구조체 시작 부분에 새 필드를 추가) 이전 초기화로 인해 예기치 않은 결과가 발생할 수 있습니다.

트릭 질문

질문: 구조체를 초기화할 때 모든 필드를 명시하지 않으면 자동 로컬 변수로 선언된 구조체는 어떻게 됩니까?

예상되는 잘못된 답변: "나머지 필드는 항상 0이 됩니다."

올바른 답변: 자동 (로컬) 변수는 명시적으로 초기화되지 않으면 초기화되지 않은 값을 유지합니다. 부분 초기화는 명시적으로 지정된 필드만 초기화하며, 나머지는 정의되지 않은 값이 됩니다 (단, = {...}로 초기화하는 경우 나머지는 정적/전역 구조체에 대해서만 0이 됩니다).

예:

void foo() { struct Point { int x, y, z; } p = {1}; // p.x == 1, p.y와 p.z == 0 (오직 = {1};를 통해서만) }

주제에 대한 미숙지로 인한 실제 오류 사례


이야기

그래픽 엔진 프로젝트에서 정점 구조체의 시작 부분에 필드를 추가했지만, 다른 모듈에서 객체 초기화 방식을 다시 검토하지 않았습니다. 그 결과, 절반의 모듈이 색상이나 좌표를 잘못 초기화하여 렌더링 결함이 나타났습니다.


이야기

비디오 처리기에서 구조체가 중첩 포인터를 부분적으로 초기화하여 = {0}으로 설정했습니다. 이는 전역 변수에 대해서는 올바르지만 로컬 변수에는 그렇지 않았습니다. 결국 포인터는 '쓰레기'를 포함하게 되어 유효하지 않은 주소로 작업하게 되었고, 이는 추적하기 어려운 충돌을 초래했습니다.


이야기

대규모 구조체에 새로운 필드를 추가할 때 저자들이 오래된 코드에서 순서 기반 초기화를 업데이트하지 않았습니다. 필드와 초기화자의 순서가 일치하지 않아 중요한 변수가 부정확한 값을 받게 되었습니다. 원인은 구조체 감사와 이름 있는 초기화 도입을 통해 밝혀졌습니다.