기본 콘텐츠로 건너뛰기

방송대 방통대 C프로그래밍 11강 - 구조체와 공용체(1) - 요약 노트 시험족보 예상문제 - 올에이클래스

C프로그래밍 11강 - 구조체와 공용체(1)

C프로그래밍 11강 - 구조체와 공용체(1)

서로 다른 자료형의 여러 항목을 하나로 묶는 구조체의 개념을 이해하고 정의·변수 선언·초기화 방법을 익힌다. typedef를 이용한 자료형 이름, 구조체 정렬과 패딩, 구조체 배열 및 구조체 포인터의 멤버 참조 방식까지 체계적으로 정리한다.

1. 구조체의 개념

원은 중심 좌표 x, y와 반지름으로 표현할 수 있고 자동차는 제조사, 모델명, 연식, 주행거리로 표현할 수 있다. 이처럼 하나의 대상을 여러 항목으로 나타내려면 관련 자료를 하나의 단위로 묶는 방법이 필요하다.

구조체(structure)는 다수의 자료를 모아 새롭게 정의한 사용자 정의 자료형이다. 배열의 모든 요소가 같은 자료형인 것과 달리 구조체를 구성하는 자료는 서로 다른 자료형일 수 있어 이형배열이라고도 설명한다.

구조체를 구성하는 각각의 자료를 멤버(member)라고 한다. 각 멤버에는 이름이 지정되며 그 이름으로 원하는 항목에 접근한다.

struct Circle {
    float x, y;
    float radius;
};

struct UsedCar {
    char maker[15];
    char modelName[15];
    int pYear, mileage;
};

구조체는 서로 관련된 여러 자료를 하나의 새 자료형으로 묶으며, 멤버마다 자료형과 이름을 지정한다.

2. 구조체 정의와 변수 선언

구조체 정의는 사용할 멤버의 구성과 자료형을 설계하는 과정이다. 정의 마지막의 세미콜론을 빠뜨리지 않아야 한다.

struct 구조체명 {
    자료형 멤버이름1;
    자료형 멤버이름2;
};

구조체를 정의하는 동시에 변수를 선언할 수도 있고, 구조체를 먼저 정의한 뒤 별도의 문장에서 변수를 선언할 수도 있다.

struct Circle {
    float x, y;
    float radius;
} c, *pCircle;

/* 또는 */
struct Circle c2, *pCircle2;
선언의미
struct Circle c;Circle 구조체 변수 c
struct Circle *pCircle;Circle 구조체를 가리키는 포인터
정의 뒤 } c;구조체 정의와 동시에 변수 선언

3. typedef를 이용한 자료형 선언

typedef는 기존 자료형에 새로운 이름을 부여하는 선언문이다. 예를 들어 typedef unsigned int UINT;를 선언하면 이후 UINT length;처럼 사용할 수 있다.

typedef struct {
    float x, y;
    float radius;
} CircleType;

CircleType c;

typedef를 구조체와 함께 사용하면 변수 선언 때마다 struct 구조체명을 반복하지 않아도 되어 자료형을 간결하게 표현할 수 있다. CircleType은 변수명이 아니라 구조체 자료형에 붙인 새 이름이다.

typedef는 새 자료형의 구조를 만드는 것이 아니라 이미 존재하는 자료형을 사용할 새로운 이름을 정한다.

4. 구조체 초기화와 멤버 참조

구조체 변수 초기화

구조체 변수는 정의된 멤버 순서에 맞춰 초깃값을 나열하여 초기화한다.

struct Person {
    char name[20];
    int age;
    float height;
};

struct Person prsn = {"홍길동", 25, 178.5f};

첫 값은 name, 둘째 값은 age, 셋째 값은 height에 들어간다. 각 초깃값의 순서와 멤버 자료형이 맞아야 한다.

점 연산자를 이용한 멤버 참조

printf("%s %d %f\n",
       prsn.name, prsn.age, prsn.height);

구조체 변수의 멤버는 구조체변수명.멤버명 형식으로 참조한다. .은 구조체 변수에 직접 적용하는 멤버 액세스 연산자이다.

5. 구조체의 기억공간과 패딩

구조체 멤버는 선언 순서대로 단순히 빈틈없이 붙는다고만 볼 수 없다. 시스템은 멤버를 효율적으로 액세스할 수 있도록 특정 바이트 경계에 맞춰 배치하는 정렬(alignment)을 적용하며, 필요한 경우 멤버 사이에 패딩(padding)을 추가한다.

typedef struct {
    int a;   /* 4 bytes */
    char b;  /* 1 byte */
    int c;   /* 4 bytes */
} StructEx;

강의 예에서 int가 4바이트일 때 a 다음의 b는 1바이트이지만 c를 적절한 경계에 배치하기 위해 b 뒤에 패딩이 추가된다. 따라서 단순 합 9바이트가 아니라 sizeof(StructEx)의 결과가 12바이트가 된다.

구조체 크기는 멤버 크기의 단순 합과 다를 수 있다. 정렬을 위한 패딩이 추가될 수 있기 때문이다.

6. 구조체 배열

기본 자료형과 같은 형식으로 구조체 배열을 선언할 수 있다. 배열의 각 요소가 하나의 완전한 구조체 변수이며, 초깃값은 요소별 중괄호 안에 멤버 순서대로 나열한다.

typedef struct {
    char name[20];
    int age;
    float height;
} Person;

Person prsn[2] = {
    {"홍길동", 25, 178.5f},
    {"박문수", 20, 180.0f}
};

구조체 배열의 멤버는 배열명[첨자].멤버명으로 참조한다.

for (int i = 0; i < 2; i++)
    printf("%s, %d, %f\n",
           prsn[i].name, prsn[i].age, prsn[i].height);

prsn[0]prsn[1]은 각각 Person 구조체 변수이고, 그 뒤의 점 연산자로 name, age, height 멤버를 선택한다.

7. 구조체 포인터

기본 자료형의 포인터와 같은 형식으로 구조체 포인터를 선언한다. 포인터에는 해당 구조체 변수의 주소를 저장한다.

Person prsn = {"홍길동", 25, 178.5f};
Person *pPrsn;
pPrsn = &prsn;

역참조와 점 연산자

printf("%s, %d, %f\n",
       (*pPrsn).name,
       (*pPrsn).age,
       (*pPrsn).height);

먼저 *pPrsn으로 구조체 변수를 얻고 점 연산자로 멤버를 선택한다. 점 연산자의 우선순위가 참조 연산자 *보다 높으므로 (*pPrsn).name처럼 괄호가 필요하다.

화살표 연산자

printf("%s, %d, %f\n",
       pPrsn->name,
       pPrsn->age,
       pPrsn->height);

구조체 포인터 전용 멤버 액세스 연산자 ->를 사용하면 더 간결하게 표현할 수 있다. pPrsn->age(*pPrsn).age와 같은 멤버를 참조한다.

대상연산자
구조체 변수.prsn.age
구조체 포인터->pPrsn->age
포인터를 역참조한 구조체.(*pPrsn).age

핵심 개념 정리

  • 구조체는 여러 자료를 모아 정의하는 사용자 정의 자료형이며 멤버의 자료형은 서로 다를 수 있다.
  • 구조체 정의는 멤버의 구성과 자료형을 정하고 구조체 변수 선언은 실제 변수를 만든다.
  • typedef는 자료형에 새로운 이름을 부여하여 구조체 자료형을 간결하게 표현한다.
  • 구조체 변수는 멤버 순서대로 초기화하고 점 연산자 .로 멤버를 참조한다.
  • 구조체는 정렬에 따라 멤버가 배치되며 필요한 경우 패딩이 추가된다.
  • 구조체 배열의 각 요소는 하나의 구조체 변수이며 배열[첨자].멤버로 접근한다.
  • 구조체 포인터는 (*p).멤버 또는 같은 의미의 p->멤버로 참조한다.

최종 정리: 구조체 변수에는 점 연산자, 구조체 포인터에는 화살표 연산자를 사용한다. 구조체의 실제 크기를 판단할 때는 멤버 크기뿐 아니라 정렬과 패딩을 고려해야 하며, typedef와 구조체 배열을 활용하면 복합 자료를 간결하게 반복 처리할 수 있다.

예상문제 20선

1. 구조체에 대한 설명으로 옳은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①
구조체는 관련된 여러 자료를 하나의 새로운 사용자 정의 자료형으로 묶는다.

2. 구조체를 구성하는 각각의 자료를 무엇이라 하는가?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②
구조체 안의 각 자료를 멤버라 하며 각 멤버는 이름으로 액세스한다.

3. 구조체 멤버의 자료형에 대한 설명은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③
구조체는 여러 종류의 자료형을 한 단위로 묶을 수 있어 이형배열로 설명된다.

4. 구조체 정의 마지막에 필요한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④
구조체 정의는 닫는 중괄호 뒤에 세미콜론을 붙여 끝낸다.

5. 이미 정의된 Circle 구조체 변수 c의 선언은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①
typedef를 쓰지 않았다면 struct 키워드와 구조체명을 함께 사용한다.

6. typedef 선언문의 기능은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②
typedef는 기존 자료형을 간결하게 사용할 새로운 이름을 정한다.

7. typedef unsigned int UINT; 이후 올바른 변수 선언은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③
UINT가 unsigned int의 새 자료형 이름처럼 사용된다.

8. 구조체 변수 초기화에서 초깃값을 배치하는 기준은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④
초깃값은 구조체 정의의 멤버 순서에 맞춰 나열한다.

9. 구조체 변수 prsn의 age 멤버 참조식은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①
구조체 변수의 멤버는 점 연산자로 직접 참조한다.

10. 구조체 멤버 사이에 패딩이 추가되는 이유는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②
정렬은 효율적인 메모리 액세스를 위해 멤버를 적절한 경계에 배치한다.

11. int 4바이트, char 1바이트인 강의의 StructEx 크기는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③
int a와 char b, int c 사이에 정렬용 패딩이 추가되어 예제 결과는 12이다.

12. 구조체 크기에 대한 설명으로 옳은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④
구조체 정렬 과정에서 빈 공간인 패딩이 추가될 수 있다.

13. Person prsn[2];의 의미는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①
배열의 각 요소가 하나의 Person 구조체 변수이다.

14. 구조체 배열 prsn의 두 번째 요소 age 멤버 참조식은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②
첨자로 배열 요소를 먼저 고른 뒤 점 연산자로 그 구조체의 멤버를 선택한다.

15. Person 구조체 포인터 pPrsn의 선언은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③
기본 자료형 포인터와 같이 자료형 뒤에 별표를 붙여 선언한다.

16. pPrsn=&prsn;의 의미는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④
주소 연산자 &로 prsn의 주소를 구해 구조체 포인터에 대입한다.

17. 구조체 포인터 pPrsn의 name 멤버를 점 연산자로 참조한 식은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①
먼저 포인터를 역참조하도록 괄호로 묶고 그 결과 구조체에 점 연산자를 적용한다.

18. 위 식에 괄호가 필요한 이유는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②
괄호가 없으면 점 연산자가 먼저 결합하므로 포인터 역참조를 먼저 수행하도록 묶는다.

19. 구조체 포인터 전용 멤버 액세스 연산자는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③
화살표 연산자는 구조체 포인터가 가리키는 구조체의 멤버를 직접 선택한다.

20. pPrsn->age와 같은 의미의 식은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④
화살표 연산자는 포인터를 역참조한 구조체에 점 연산자를 적용한 것과 같다.

댓글