C언어 초급 - 13장: 구조체와 공용체 (13.1 구조체 (struct))

2025. 2. 24. 12:05프로그래밍 언어/C

13.1 구조체 (struct)

C 언어에서 구조체(Structure, struct)여러 개의 변수를 하나의 그룹으로 묶어서 관리할 수 있는 사용자 정의 데이터 타입입니다.
서로 다른 자료형(정수, 실수, 문자열 등) 을 하나의 구조체로 묶어서 저장할 수 있습니다.

구조체의 주요 특징

  • 서로 다른 데이터 타입을 하나로 묶을 수 있음.
  • 배열과 달리, 여러 개의 데이터 타입을 포함 가능.
  • 배열처럼 구조체 변수를 선언할 수 있으며, 구조체 포인터를 사용할 수 있음.
  • 파일 저장 및 네트워크 데이터 전송에 활용됨.

1. 구조체 선언 및 사용

1.1 구조체 선언

구조체는 struct 키워드를 사용하여 선언합니다.

📌 기본 문법

struct 구조체이름 {
    자료형 변수1;
    자료형 변수2;
    ...
};

📌 구조체 선언 예제

#include <stdio.h>

// 구조체 선언
struct Student {
    char name[20];  // 학생 이름
    int age;        // 나이
    float score;    // 점수
};

int main() {
    struct Student s1 = {"홍길동", 20, 95.5};  // 구조체 변수 선언 및 초기화

    printf("이름: %s\n", s1.name);
    printf("나이: %d\n", s1.age);
    printf("점수: %.1f\n", s1.score);

    return 0;
}

출력 결과

이름: 홍길동
나이: 20
점수: 95.5

📌 설명

  • struct Student { ... }; → 구조체를 선언.
  • struct Student s1 = {"홍길동", 20, 95.5}; → 구조체 변수 선언 및 초기화.
  • s1.name, s1.age, s1.score → 구조체 멤버 변수 접근.

구조체를 사용하면 다양한 데이터를 하나로 묶어서 다룰 수 있음.


1.2 typedef를 사용한 구조체 선언

C 언어에서는 typedef를 사용하여 구조체 이름을 줄일 수 있습니다.

📌 typedef를 활용한 구조체 선언

#include <stdio.h>

// typedef를 사용하여 구조체 별칭 정의
typedef struct {
    char name[20];
    int age;
    float score;
} Student;

int main() {
    Student s1 = {"이순신", 25, 88.5};  // typedef로 줄인 구조체 선언

    printf("이름: %s, 나이: %d, 점수: %.1f\n", s1.name, s1.age, s1.score);

    return 0;
}

📌 설명

  • typedef struct { ... } Student; → struct Student 대신 Student로 사용 가능.
  • Student s1; → struct 키워드 없이 간결한 선언 가능.

구조체 변수를 선언할 때 struct 키워드를 생략할 수 있어 가독성이 좋아짐!


2. 구조체 배열

구조체 배열을 사용하면 여러 개의 구조체 변수를 하나의 배열로 관리할 수 있습니다.

📌 구조체 배열 선언 예제

#include <stdio.h>

typedef struct {
    char name[20];
    int age;
    float score;
} Student;

int main() {
    Student students[3] = {
        {"홍길동", 20, 95.5},
        {"이순신", 25, 88.0},
        {"김유신", 23, 91.2}
    };

    // 구조체 배열 출력
    for (int i = 0; i < 3; i++) {
        printf("이름: %s, 나이: %d, 점수: %.1f\n",
               students[i].name, students[i].age, students[i].score);
    }

    return 0;
}

출력 결과

이름: 홍길동, 나이: 20, 점수: 95.5
이름: 이순신, 나이: 25, 점수: 88.0
이름: 김유신, 나이: 23, 점수: 91.2

📌 설명

  • Student students[3] = {...}; → 구조체 배열 선언 및 초기화.
  • students[i].name, students[i].age, students[i].score → 배열 요소의 구조체 멤버 접근.

구조체 배열을 사용하면 여러 개의 데이터를 효과적으로 관리할 수 있음.


3. 구조체 포인터

구조체 포인터를 사용하면 구조체 변수를 동적으로 관리하거나 함수에 구조체를 효율적으로 전달할 수 있습니다.

3.1 구조체 포인터 선언

struct Student *ptr;

📌 구조체 포인터를 사용한 예제

#include <stdio.h>

typedef struct {
    char name[20];
    int age;
    float score;
} Student;

int main() {
    Student s1 = {"홍길동", 20, 95.5};
    Student *ptr = &s1;  // 구조체 포인터 선언 및 주소 저장

    // 구조체 포인터를 사용한 멤버 접근
    printf("이름: %s\n", ptr->name);
    printf("나이: %d\n", ptr->age);
    printf("점수: %.1f\n", ptr->score);

    return 0;
}

출력 결과

이름: 홍길동
나이: 20
점수: 95.5

📌 설명

  • Student *ptr = &s1; → 구조체 변수 s1의 주소를 저장.
  • ptr->name, ptr->age, ptr->score → -> 연산자로 구조체 멤버 접근.

구조체 포인터를 사용하면 메모리 효율적인 프로그래밍이 가능!


4. 동적 메모리를 활용한 구조체 포인터

구조체 포인터를 사용하면 malloc()을 이용하여 동적으로 구조체 메모리를 할당할 수 있습니다.

📌 동적 메모리 할당 예제

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    char name[20];
    int age;
    float score;
} Student;

int main() {
    // 구조체 포인터를 사용한 동적 메모리 할당
    Student *ptr = (Student *)malloc(sizeof(Student));

    if (ptr == NULL) {
        printf("메모리 할당 실패\n");
        return 1;
    }

    // 구조체 멤버 값 설정
    printf("이름 입력: ");
    scanf("%s", ptr->name);
    printf("나이 입력: ");
    scanf("%d", &ptr->age);
    printf("점수 입력: ");
    scanf("%f", &ptr->score);

    // 출력
    printf("이름: %s, 나이: %d, 점수: %.1f\n", ptr->name, ptr->age, ptr->score);

    free(ptr);  // 동적 메모리 해제
    return 0;
}

📌 설명

  • malloc(sizeof(Student)) → 동적으로 구조체 메모리 할당.
  • ptr->name, ptr->age, ptr->score → 구조체 멤버 접근.
  • free(ptr); → 메모리 누수를 방지하기 위해 반드시 free() 호출.

구조체 동적 할당을 사용하면, 실행 중 필요한 만큼 메모리를 할당할 수 있음.


5. 정리

개념  설명  예제
구조체 선언 여러 개의 변수를 하나로 묶음 struct Student { char name[20]; int age; };
구조체 변수 구조체 타입 변수 선언 struct Student s1;
구조체 배열 구조체 데이터를 배열로 관리 Student students[3];
구조체 포인터 구조체 주소를 저장하여 접근 Student *ptr = &s1;
동적 구조체 메모리 할당 malloc()을 이용한 구조체 메모리 동적 할당 Student *p = (Student *)malloc(sizeof(Student));

📌 구조체를 사용하면 다양한 데이터 타입을 하나로 묶어 관리할 수 있음
📌 배열과 포인터를 함께 사용하면 데이터를 더욱 효율적으로 관리 가능
📌 메모리 동적 할당(malloc())을 활용하면 실행 중에 필요한 만큼 구조체를 생성 가능