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;
위와 같이 선언하면 INTEGER는 int와 동일한 역할을 수행합니다.
#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 = #
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
• 코드 간결성 향상 (
struct 키워드 생략)• 자료형 이름의 직관성 증가
• 코드 유지보수 용이
• 플랫폼 독립적 코드 작성에 유리
4. 종합 실습
문제 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 - 구조체 배열 (기초)
다음 코드의 실행 결과는?
{% 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 선언 (기초)
다음 중 올바른 typedef 선언은?
A. typedef int INTEGER;
B. typedef struct point POINT;
C. typedef char * STRING;
D. 위의 모든 선언이 올바르다.
문제 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 - 구조체 배열과 반복문 (중급)
다음 코드의 실행 결과는?
{% 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 - 구조체 멤버 접근 (고급)
다음 코드의 실행 결과는?
{% 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 %}
핵심 요약
• 선언:
struct 구조체이름 { 멤버변수들; };• 여러 자료형을 하나로 묶는 사용자 정의 자료형
• 멤버 변수는 개수 제한 없음
• 각 멤버는 독립적인 메모리 공간 할당
2. 구조체 변수 선언 및 접근
• 선언:
struct 구조체이름 변수이름;• 멤버 접근:
변수이름.멤버이름 (도트 연산자 사용)• 초기화:
struct 구조체이름 변수 = {값1, 값2, ...};3. 구조체 배열
• 선언:
struct 구조체이름 배열이름[크기];• 초기화:
{{값1, 값2}, {값3, 값4}, ...}• 접근:
배열이름[인덱스].멤버이름4. typedef 선언
• 기본 형식:
typedef 기존자료형 새이름;• 구조체:
typedef struct 구조체이름 새이름;• 정의와 동시 선언:
typedef struct { ... } 새이름;• struct 키워드 생략 가능
5. 사용 시 주의사항
• 구조체 멤버 접근 시 . 연산자 필수
• 배열 초기화는 선언 시에만 리스트 사용 가능
• typedef 사용 시 코드 간결성 향상
• 구조체는 논리적으로 관련된 데이터를 묶을 때 사용