6. 구조체 기본

header


1. 구조체의 이해

구조체(Structure)는 다양한 데이터형을 갖는 변수들의 집합입니다. 하나 이상의 변수를 묶어서 새로운 사용자 정의 자료형을 만들 수 있습니다.

구조체란?

구조체는 사용자가 임의로 정의하는 새로운 유형의 자료형이라는 의미로 사용자 정의 자료형이라고도 불립니다.

struct person
{
    char name[30];
    int age;
};
구조체의 특징
struct 키워드로 정의
• 여러 자료형을 하나로 묶을 수 있음
• 각 멤버 변수는 독립적인 메모리 공간 할당
• 사용자 정의 자료형으로 활용

구조체 변수의 선언

구조체 정의가 완료되면 구조체 변수를 선언할 수 있습니다.

struct person boy;
struct person girl;

메모리 할당:

boy 구조체 변수
┌────────────────┬────┐
│ name[30]       │age │
└────────────────┴────┘

girl 구조체 변수
┌────────────────┬────┐
│ name[30]       │age │
└────────────────┴────┘

구조체 멤버 변수 접근

멤버 변수에 접근할 때는 . 연산자(도트 연산자)를 사용합니다.

#include <stdio.h>
#include <string.h>

struct person
{
    char name[30];
    int age;
};

int main(void)
{
    struct person boy, girl;

    // name 멤버 변수에 대한 접근
    strcpy(boy.name, "김선호");
    strcpy(girl.name, "이소녀");

    // age 멤버 변수에 대한 접근
    boy.age = 12;
    girl.age = 9;

    printf("소년의 이름은 %s, 나이는 %d세\n", boy.name, boy.age);
    printf("소녀의 이름은 %s, 나이는 %d세\n", girl.name, girl.age);

    return 0;
}
실행 결과 보기
소년의 이름은 김선호, 나이는 12세
소녀의 이름은 이소녀, 나이는 9세

구조체 변수의 초기화

구조체 변수는 선언과 동시에 초기화할 수 있으며, 배열과 유사한 문법을 사용합니다.

struct person boy = {"김선호", 12};
#include <stdio.h>

struct person
{
    char name[30];
    int age;
};

int main(void)
{
    // 구조체 변수 선언과 동시에 초기화
    struct person boy = {"김선호", 12};
    struct person girl = {"이소녀", 9};

    printf("소년의 이름은 %s, 나이는 %d세\n", boy.name, boy.age);
    printf("소녀의 이름은 %s, 나이는 %d세\n", girl.name, girl.age);

    return 0;
}
실행 결과 보기
소년의 이름은 김선호, 나이는 12세
소녀의 이름은 이소녀, 나이는 9세
💡 구조체를 사용하는 이유
• 관련된 데이터를 논리적으로 묶어 관리
• 코드의 가독성과 유지보수성 향상
• 복잡한 데이터 구조를 효율적으로 표현

2. 구조체와 배열

구조체는 사용자 정의 자료형이므로 구조체 배열을 선언할 수 있습니다.

구조체 배열의 선언

int iarr[3];              // 일반 배열
struct person parr[3];    // 구조체 배열

메모리 구조:

int형 배열 iarr
┌─────┬─────┬─────┐
│ int │ int │ int │
└─────┴─────┴─────┘

person 구조체 배열 parr
┌──────────────┬──────────────┬──────────────┐
│   name  age  │   name  age  │   name  age  │
│ [30]    int  │ [30]    int  │ [30]    int  │
└──────────────┴──────────────┴──────────────┘

구조체 배열의 초기화

#include <stdio.h>
#include <string.h>

struct person
{
    char name[30];
    int age;
};

int main(void)
{
    // 구조체 배열의 선언 및 초기화
    struct person boy[3] = {
        {"김소년", 12},
        {"유소년", 14},
        {"청소년", 16}
    };

    struct person girl[3];
    int i;

    // 개별 변수에 대한 초기화
    strcpy(girl[0].name, "이소녀");
    strcpy(girl[1].name, "오소녀");
    strcpy(girl[2].name, "하소녀");
    girl[0].age = 9;
    girl[1].age = 13;
    girl[2].age = 7;

    for(i = 0; i < 3; i++)
    {
        printf("소년의 이름은 %s, 나이는 %d세\n", boy[i].name, boy[i].age);
        printf("소녀의 이름은 %s, 나이는 %d세\n", girl[i].name, girl[i].age);
    }

    return 0;
}
실행 결과 보기
소년의 이름은 김소년, 나이는 12세
소녀의 이름은 이소녀, 나이는 9세
소년의 이름은 유소년, 나이는 14세
소녀의 이름은 오소녀, 나이는 13세
소년의 이름은 청소년, 나이는 16세
소녀의 이름은 하소녀, 나이는 7세
구조체 배열 초기화 방법
• 선언 시 초기화 리스트 사용: {{"값1", 값2}, {"값3", 값4}, ...}
• 각 배열 요소에 개별 접근하여 초기화
• 배열의 인덱스와 . 연산자 함께 사용: arr[i].member

3. typedef 선언

typedef기존 자료형에 새 이름을 부여하는 선언입니다. 복잡한 자료형을 간결하게 사용할 수 있습니다.

typedef 기본 사용법

typedef int INTEGER;

위와 같이 선언하면 INTEGERint와 동일한 역할을 수행합니다.

#include <stdio.h>

// int형 정수, int형 정수 포인터, 부호 없는 int형 정수에 각각 별칭 부여
typedef int INT;
typedef int * PINT;
typedef unsigned int UINT;

int main(void)
{
    // 지역 내에서 사용할 자료형 이름에 대한 선언
    typedef char CHAR;
    typedef char * STR;

    // typedef 선언 이후 자료형은 기존 자료형과 동일한 역할을 수행
    INT num = 3;
    PINT ptr = &num;
    UINT unum = 5;

    CHAR ch = 'c';
    STR str = "Hello!";

    printf("%d %d %d\n", num, *ptr, unum);
    printf("%c %s\n", ch, str);

    return 0;
}
실행 결과 보기
3 3 5
c Hello!
기존 자료형 별칭
int INT
int * PINT
unsigned int UINT
char CHAR
char * STR

구조체와 typedef

구조체를 typedef로 선언하면 struct 키워드를 생략할 수 있어 편리합니다.

struct point
{
    int x;
    int y;
};

typedef struct point POINT;

이제 구조체 변수 선언 시 다음과 같이 사용할 수 있습니다.

POINT position = {30, 60};

구조체 정의와 동시에 typedef 선언

더 간결하게 구조체를 정의하면서 동시에 typedef 선언을 할 수 있습니다.

typedef struct
{
    int x;
    int y;
} POINT;
#include <stdio.h>

// 구조체 선언과 동시에 typedef 선언
typedef struct
{
    int x;
    int y;
} POINT;

struct person
{
    char name[30];
    int age;
};

// 정의된 구조체에 대한 typedef 선언
typedef struct person PERSON;

int main(void)
{
    POINT position = {30, 60};
    PERSON saram = {"김사람", 10};

    printf("%d %d\n", position.x, position.y);
    printf("%s %d\n", saram.name, saram.age);

    return 0;
}
실행 결과 보기
30 60
김사람 10
💡 typedef 사용의 장점
• 코드 간결성 향상 (struct 키워드 생략)
• 자료형 이름의 직관성 증가
• 코드 유지보수 용이
• 플랫폼 독립적 코드 작성에 유리

4. 종합 실습

문제 1 - 구조체 기본 (기초)

문제 1

다음 코드의 실행 결과는?

{% capture code_block1 %}

#include <stdio.h>

struct student {
    int id;
    int score;
};

int main(void) {
    struct student s = {20230101, 95};

    printf("%d", s.score);

    return 0;
}

{% endcapture %}

구조체 기본

문제 2 - 구조체 배열 (기초)

문제 2

다음 코드의 실행 결과는?

{% capture code_block2 %}

#include <stdio.h>

struct point {
    int x;
    int y;
};

int main(void) {
    struct point arr[3] = {{1, 2}, {3, 4}, {5, 6}};

    printf("%d", arr[1].x + arr[2].y);

    return 0;
}

{% endcapture %}

구조체 기본

문제 3 - typedef 선언 (기초)

문제 3

다음 중 올바른 typedef 선언은?

A. typedef int INTEGER;
B. typedef struct point POINT;
C. typedef char * STRING;
D. 위의 모든 선언이 올바르다.
구조체 기본

문제 4 - 구조체 초기화 (중급)

문제 4

다음 코드의 실행 결과는?

{% capture code_block4 %}

#include <stdio.h>

typedef struct {
    int num;
    int score;
} Student;

int main(void) {
    Student s1 = {1, 80};
    Student s2 = {2, 90};

    int total = s1.score + s2.score;

    printf("%d", total);

    return 0;
}

{% endcapture %}

구조체 기본

문제 5 - 구조체 배열과 반복문 (중급)

문제 5

다음 코드의 실행 결과는?

{% capture code_block5 %}

#include <stdio.h>

typedef struct {
    int value;
} Data;

int main(void) {
    Data arr[4] = {{10}, {20}, {30}, {40}};
    int sum = 0;
    int i;

    for(i = 0; i < 4; i++) {
        sum += arr[i].value;
    }

    printf("%d", sum);

    return 0;
}

{% endcapture %}

구조체 기본

문제 6 - 구조체 멤버 접근 (고급)

문제 6

다음 코드의 실행 결과는?

{% capture code_block6 %}

#include <stdio.h>

typedef struct {
    int a;
    int b;
} Pair;

int main(void) {
    Pair p1 = {5, 10};
    Pair p2 = {3, 7};

    int result = (p1.a + p2.a) * (p1.b - p2.b);

    printf("%d", result);

    return 0;
}

{% endcapture %}

구조체 기본
(5 + 3) * (10 - 7) = 8 * 3 = 24

핵심 요약

1. 구조체의 정의
• 선언: struct 구조체이름 { 멤버변수들; };
• 여러 자료형을 하나로 묶는 사용자 정의 자료형
• 멤버 변수는 개수 제한 없음
• 각 멤버는 독립적인 메모리 공간 할당

2. 구조체 변수 선언 및 접근
• 선언: struct 구조체이름 변수이름;
• 멤버 접근: 변수이름.멤버이름 (도트 연산자 사용)
• 초기화: struct 구조체이름 변수 = {값1, 값2, ...};

3. 구조체 배열
• 선언: struct 구조체이름 배열이름[크기];
• 초기화: {{값1, 값2}, {값3, 값4}, ...}
• 접근: 배열이름[인덱스].멤버이름

4. typedef 선언
• 기본 형식: typedef 기존자료형 새이름;
• 구조체: typedef struct 구조체이름 새이름;
• 정의와 동시 선언: typedef struct { ... } 새이름;
• struct 키워드 생략 가능

5. 사용 시 주의사항
• 구조체 멤버 접근 시 . 연산자 필수
• 배열 초기화는 선언 시에만 리스트 사용 가능
• typedef 사용 시 코드 간결성 향상
• 구조체는 논리적으로 관련된 데이터를 묶을 때 사용