Topic 4: 복합 자료구조 🏗️🔧
🎯 학습 목표
- 구조체, 열거형, 공용체를 조합한 복합 자료구조를 설계할 수 있다
- 중첩 구조체와 구조체 내 포인터를 효과적으로 활용할 수 있다
- 실제 프로젝트에서 사용할 수 있는 데이터 구조를 구현할 수 있다
- 메모리 효율성과 코드 가독성을 고려한 설계를 할 수 있다
🧩 복합 자료구조란?
복합 자료구조는 기본 자료형들을 조합하여 만든 구조체, 열거형, 공용체를 더 복잡하고 실용적인 형태로 결합한 것입니다.
실제 프로그램에서는 단순한 구조체보다는 여러 구조체가 서로 연결되고, 포인터로 참조하며, 열거형으로 상태를 관리하는 복합적인 구조가 필요합니다! 🏢
🏢 중첩 구조체 (Nested Structures)
중첩 구조체란?
중첩 구조체는 구조체 안에 다른 구조체를 포함하는 것입니다. 마치 러시아 인형 🪆 처럼 안에 또 다른 인형이 들어있는 것과 같아요!
간단한 예제: 학생과 주소
#include <iostream>
#include <string>
using namespace std;
// 주소 정보 구조체
struct Address {
string city;
string district;
void display() {
cout << city << " " << district;
}
};
// 학생 정보 구조체 (Address를 포함)
struct Student {
string name;
int age;
Address home; // 중첩 구조체!
void showInfo() {
cout << "이름: " << name << endl;
cout << "나이: " << age << "세" << endl;
cout << "주소: ";
home.display();
cout << endl;
}
};
int main() {
Student student1;
student1.name = "김철수";
student1.age = 20;
student1.home.city = "서울";
student1.home.district = "강남구";
student1.showInfo();
return 0;
}
출력:
이름: 김철수
나이: 20세
주소: 서울 강남구
🏗️ 복합 자료구조 설계 원리
복합 자료구조란?
복합 자료구조는 기본 구조체들을 조합하여 실제 세계의 복잡한 관계를 프로그램으로 표현하는 것입니다.
단순한 구조체
struct Student {
string name;
int age;
double grade;
};
복합 자료구조
struct Address {
string street;
string city;
string zipCode;
};
struct Student {
string name;
int age;
Address homeAddress; // 구조체 안에 구조체!
vector<int> scores; // 여러 과목 점수
};
왜 중첩 구조체를 사용할까?
비유로 이해하기: 🏠 집주소를 생각해보세요!
- 전체 주소 = 큰 구조체
- 시/구/동 = 작은 구조체들
- 각각은 독립적이지만 함께 완전한 정보를 만듭니다
장점들:
- 정리정돈: 관련 정보끼리 묶어서 관리
- 재사용: Address 구조체를 여러 곳에서 사용 가능
- 이해 쉬움: 코드가 실제 세계와 비슷한 구조
단계별 설계 방법
1단계: 작은 구조체부터 만들기
// 점수 정보
struct Score {
int math;
int english;
int science;
};
2단계: 큰 구조체에 포함하기
// 학생 정보 (Score를 포함)
struct Student {
string name;
int grade; // 학년
Score scores; // 중첩 구조체!
double getAverage() {
return (scores.math + scores.english + scores.science) / 3.0;
}
};
간단한 게임 캐릭터 예제
// 캐릭터 능력치
struct Stats {
int hp;
int mp;
int attack;
};
// 위치 정보
struct Position {
int x;
int y;
};
// 게임 캐릭터 (중첩 구조체 사용)
struct Character {
string name;
int level;
Stats abilities; // 능력치 구조체
Position location; // 위치 구조체
void showStatus() {
cout << name << " (Lv." << level << ")" << endl;
cout << "HP: " << abilities.hp << endl;
cout << "MP: " << abilities.mp << endl;
cout << "위치: (" << location.x << ", " << location.y << ")" << endl;
}
};
실습: 간단한 카페 메뉴
#include <iostream>
#include <string>
using namespace std;
// 가격 정보
struct Price {
int regular;
int large;
};
// 메뉴 아이템
struct MenuItem {
string name;
Price price; // 중첩 구조체
bool available;
void display() {
cout << name;
if (available) {
cout << " - R: " << price.regular << "원, L: " << price.large << "원";
} else {
cout << " (품절)";
}
cout << endl;
}
};
int main() {
MenuItem coffee;
coffee.name = "아메리카노";
coffee.price.regular = 3000;
coffee.price.large = 3500;
coffee.available = true;
coffee.display();
return 0;
}
출력:
아메리카노 - R: 3000원, L: 3500원
중첩 구조체 사용 팁
간단하게 유지하기
// ✅ 이해하기 쉬운 구조
struct Person {
string name;
Address home; // 한 단계 중첩
};
// ❌ 너무 복잡한 구조
struct Complex {
struct {
struct {
int value;
} level3;
} level2;
};
// 접근: complex.level2.level3.value (복잡!)
의미있는 이름 사용
// ✅ 명확한 이름
struct Student {
string name;
Address home; // 집 주소
Address school; // 학교 주소
};
// ❌ 혼란스러운 이름
struct Student {
string name;
Address addr1; // 뭐의 주소?
Address addr2; // 뭐의 주소?
};
실제 예시: 온라인 쇼핑몰
간단한 구조 설계:
온라인 쇼핑몰
├── 상품 정보
├── 고객 정보
└── 주문 정보
코드로 표현하면:
struct Product {
string name;
int price;
};
struct Customer {
string name;
Address delivery; // 배송 주소
};
struct Order {
Customer buyer; // 구매자
Product item; // 상품
int quantity; // 수량
};
중요한 설계 원칙
- 간단하게: 2-3단계 이상 깊이 중첩하지 않기
- 관련성: 함께 사용되는 데이터끼리 묶기
- 명확성: 구조체 이름과 멤버 이름을 명확하게
- 실용성: 실제로 필요한 기능만 포함하기
🧪 퀴즈 타임!
🤔 퀴즈 1: 중첩 구조체의 메모리 크기는?
struct Inner {
int a; // 4 bytes
char b; // 1 byte
}; // 패딩으로 총 8 bytes
struct Outer {
Inner inner; // 8 bytes
double c; // 8 bytes
};
정답: 16 bytes
Inner 구조체는 패딩으로 인해 8 bytes, double은 8 bytes이므로 총 16 bytes입니다.
🤔 퀴즈 2: 다음 코드의 출력은?
enum class Status { ACTIVE, INACTIVE };
struct Data {
int id;
Status status;
};
int main() {
Data d = {100, Status::ACTIVE};
cout << d.id << " " << static_cast<int>(d.status);
return 0;
}
정답: 100 0
id는 100이고, Status::ACTIVE는 0번째 값이므로 0이 출력됩니다.
🤔 퀴즈 3: 복합 자료구조의 장점이 아닌 것은?
- 관련 데이터를 그룹화하여 관리 용이성 향상
- 코드의 가독성과 유지보수성 향상
- 메모리 사용량 최소화
- 실제 세계의 복잡한 관계를 모델링 가능
정답: 3번 (메모리 사용량 최소화)
복합 자료구조는 구조화와 가독성에 중점을 둔 것이지, 메모리 사용량을 최소화하는 것이 주 목적은 아닙니다.
🎯 연습 문제
연습 1: 학생 성적 관리
학생의 이름, 학번, 그리고 3과목 점수를 저장하는 중첩 구조체를 만들어보세요.
💡 힌트
- Score 구조체로 3과목 점수를 묶으세요
- Student 구조체에 Score를 포함하세요
- 평균 점수를 계산하는 함수를 만드세요
연습 2: 게임 캐릭터 만들기
캐릭터의 이름, 레벨, 능력치(HP, MP, 공격력), 위치(x, y)를 중첩 구조체로 설계해보세요.
💡 힌트
- Stats 구조체로 능력치들을 묶으세요
- Position 구조체로 위치 정보를 묶으세요
- Character 구조체에 모든 정보를 포함하세요
연습 3: 간단한 주소록
사람의 이름, 나이, 집 주소, 전화번호를 저장하는 구조체를 만들어보세요.
💡 힌트
- Address 구조체로 주소 정보를 만드세요
- Person 구조체에 개인정보와 Address를 포함하세요
- 정보를 출력하는 함수를 만드세요
🎉 마무리
중첩 구조체는 관련된 정보를 체계적으로 정리하는 훌륭한 방법입니다!
오늘 배운 내용:
- 🏗️ 중첩 구조체의 개념과 필요성
- 📦 작은 구조체들을 조합하여 큰 구조체 만들기
- 🎯 실제 사용 예제들 (학생, 게임 캐릭터, 카페 메뉴)
- 💡 좋은 설계를 위한 기본 원칙들
다음 단계:
- Unit 8에서는 포인터와 메모리 관리를 학습합니다
- 구조체와 포인터를 함께 사용하는 방법을 배웁니다
- 더 효율적인 메모리 사용법을 익히게 됩니다
이제 여러분은 관련된 데이터들을 체계적으로 정리할 수 있는 능력을 갖추었습니다!