C - 구조체 (Structure)

lsjoon·2024년 2월 3일

C

목록 보기
6/8

구조체

구조체의 원소(= 구성원, 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
위의 변수들은 선언과 동시에 초기화
*/

[C99] 지정 초기자

- 장점

  • 명백하게 구조체의 구성원과 초기자 값의 1:1 대응 확인 가능
  • 초기자의 값들은 구조체의 구성원과 같은 순서일 필요가 없음
  • 지정 초기자에 있는 모든 값에 반드시 지정자(구두점 + 구성원 이름)를 적어줘야 할 필요 없음
    = '지정자가 없는 값'에 대해 컴파일러는 '지정자가 설정된 구성원'의 다음 구성원으로 초기화할 것을 가정 ( 초기자 식별을 실패할 경우, 나머지 구성원들은 0으로 설정 )
{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


입력값과 반환값으로서의 구조체

  1. 입력변수로 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");
}
  1. 받은 입력변수로부터 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);
  1. 함수 안에서 구조체 변수를 다른 구조체와 같도록 초기화
void f(struct part part1) {
	struct part part2 = part1;

위처럼 구조체를 함수에 전달하거나, 함수에서 구조체를 반환받는 경우 프로그램에 부하를 가하게 될 수 있음
- Why? 함수에 구조체의 모든 구성원을 복사해 감
- 해결책 : 구조체 자체를 함수에서 호출하기 보다, 포인터를 활용



[ C99 ] 복합리터럴 활용

복합리터럴 : 이름 없는 배열을 만듦 ( 주로 일회용으로 함수에 전달할 목적 )

복합리터럴은 구조체를 변수에 저장할 필요 없이 "즉시" 생성하는데 사용 가능
복합리터럴을 통해 생성한 구조체의 활용방법 :
- 매개변수에 전달
- 함수에서 반환
- 변수에 할당

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 });


출처

profile
중요한 것은 꺾여도 그냥 하는 마음

0개의 댓글