구조체의 원소(= 구성원, Member)는 같은 형(Type)일 필요가 없음
구조체의 구성원들은 각각의 이름을 가지며, 특정 구성원을 선택하기 위해선 위치가 아닌 이름을 특정해주어야 함
- 서로 유관한 데이터의 집합을 저장하기 위해선 구조체가 합리적
- 각 구조체들은 새로운 스코프를 가지며, 프로그램 내의 다른 이름과 충돌을 일으키지 않음
= 각 구조체들은 서로 다른 이름 공간(name space)을 가짐
ex. 창고에서 부품들을 추적하는 장부 만들기
< 저장해야할 정보>
1. 부품 번호 (정수)
2. 부품 이름 (문자열)
3. 보유한 부품 개수 (정수)
struct {
int number;
char name[NAME_LEN + 1];
int on_hand;
} part1 = {528, "Disk drive", 10},
part2 = {914, "Printer cable", 5};
/*
구조체 변수가 갖는 구성원(Member) : number, name, on_hand
해당 구조체의 변수 : part1, part2
위의 변수들은 선언과 동시에 초기화
*/
- 장점
{528, "Disk drive", 10}
{.number = 528, .name = "Disk drive", .on_hand = 10}
// 지정자 : '.name' 처럼 앞에 .이 붙고, 뒤에 이름이 오는 형식
{.number = 528, "Disk drive", .on_hand = 10}
// "Disk drive" 는 구조체에서 number 다음에 나오는 구성원으로 초기화 예정
// 초기자가 식별을 실패할 경우, 나머지 구성원들은 0으로 설정
구조체 태그란 특정 구조체를 식별할 때 사용하는 이름
- 구조체 태그는 앞에 struct 가 붙어야 의미가 생기므로, 프로그램 내에 part 라는 이름을 가진 변수를 선언해도 충돌이 생기지 않음
struct part {
int number;
char name[NAME_LEN + 1];
int on_hand;
}; // << 구조체 선언문 중괄호 끝에 세미 콜론이 옴 !!!!!
struct part part1;
struct part part2;
struct part part3 = {528, "Disk drive", 10};
part1 = part3 // 할당 가능
구조체 태그 선언 외에, typedef 를 사용하여 실제 형명을 정의 가능
- struct 와 달리, 형명인 Part 가 마지막에 옴
typedef strcut {
int number;
char name[NAME_LEN + 1];
int on_hand;
} Part;
Part part1
Part part2
part 구조체가 주어질 때, 구조체 구성원을 출력void print_part(struct part p) {
printf("Part number: %d\n", p.number);
printf("Part name: %s\n", p.name);
printf("Quantity on hand: %d\n");
}
part 구조체를 만들어 반환하는 함수struct part build_part(int number, const char* name, int on_hand) {
struct part p;
p.number = number;
strcpy(p.name, name);
p.on_hand = on_hand;
return p;
}
part = build_part(528, "Disk drive", 10);
void f(struct part part1) {
struct part part2 = part1;
위처럼 구조체를 함수에 전달하거나, 함수에서 구조체를 반환받는 경우 프로그램에 부하를 가하게 될 수 있음
- Why? 함수에 구조체의 모든 구성원을 복사해 감
- 해결책 : 구조체 자체를 함수에서 호출하기 보다, 포인터를 활용
복합리터럴 : 이름 없는 배열을 만듦 ( 주로 일회용으로 함수에 전달할 목적 )
복합리터럴은 구조체를 변수에 저장할 필요 없이 "즉시" 생성하는데 사용 가능
복합리터럴을 통해 생성한 구조체의 활용방법 :
- 매개변수에 전달
- 함수에서 반환
- 변수에 할당
void print_part(struct part p) {
printf("Part number: %d\n", p.number);
printf("Part name: %s\n", p.name);
printf("Quantity on hand: %d\n");
}
// 1. 복합리터럴은 part 구조체 생성하면서, print_part 함수에 전달
print_part(
(struct part) { 528, "Disk drive", 10 }
);
// 2. 구성원으로 528, "Disk drive", 10 을 가지는 part 구조체 생성
/* 초기자처럼 보이지만, 초기자는 선언에서만 등장 가능 */
part1 = (struct part) { 528, "Disk drive", 10 };
// 3. 지정자 사용 시 전부 초기화하지 않는다면, 초기화 하지 않은 구성원은 0 값을 가짐
print_part((struct part) ( .on_hand = 10,
.name = "Disk drive",
.number = 528 });