산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> C 언어

C 구조체 마스터: 정의, 멤버 접근, 중첩, 정렬, 패딩, 비트필드

구조체(struct)는 서로 다른 타입의 변수들을 하나로 묶어 사용자 정의 타입을 만드는 핵심 기능입니다. 레코드 표현, 자료구조, 하드웨어 매핑 등에 필수적입니다.

구조체 정의와 선언

// 태그 있는 구조체
struct Point {
    int x;
    int y;
};

// typedef로 별칭 생성 (권장)
typedef struct {
    char name[50];
    int age;
    double salary;
} Employee;

// 태그 + typedef 동시
typedef struct Node {
    int data;
    struct Node *next;  // 자기 참조 포인터 (태그 필요)
} Node;

변수 선언과 초기화

struct Point p1;                    // 선언
struct Point p2 = {10, 20};         // 순서대로 초기화
struct Point p3 = {.x = 10, .y = 20}; // 지정 초기화자 (C99, 순서 무관)
Employee e = {"Alice", 30, 50000.0};
Node *head = NULL;

멤버 접근

구조체 복사/대입/비교

struct Point a = {1,2}, b;
b = a;  // OK: 멤버별 복사

// 비교 함수
int point_eq(struct Point a, struct Point b) {
    return a.x == b.x && a.y == b.y;
}

중첩 구조체

struct Date { int y, m, d; };

struct Person {
    char name[32];
    struct Date birth;  // 중첩 구조체 (값 포함)
    struct Date *hired; // 포인터로 참조
};

struct Person p = {
    .name = "Bob",
    .birth = {1990, 5, 15},  // 중첩 초기화
    .hired = &(struct Date){2020, 1, 1}  // 복합 리터럴 (C99)
};

printf("%d-%02d-%02d\n", p.birth.y, p.birth.m, p.birth.d);

메모리 레이아웃: 정렬(Alignment)과 패딩(Padding)

struct Example {
    char c;      // 1바이트, 오프셋 0
    // 패딩 3바이트 (다음 int 정렬 위해)
    int i;       // 4바이트, 오프셋 4
    double d;    // 8바이트, 오프셋 8 (8의 배수)
    // 패딩 없음 (이미 16의 배수)
};
// 크기: 24바이트 (1 + 3패딩 + 4 + 8 + 8패딩? → 실제 24)

// 멤버 순서 재배치로 크기 절약
struct Optimized {
    double d;    // 오프셋 0
    int i;       // 오프셋 8
    char c;      // 오프셋 12
    // 패딩 3바이트 → 총 16바이트
};

패딩 확인 매크로

#define OFFSET_OF(type, member) ((size_t)&(((type*)0)->member))
#define SIZE_OF(type) sizeof(type)

printf("c offset: %zu\n", OFFSET_OF(struct Example, c));  // 0
printf("i offset: %zu\n", OFFSET_OF(struct Example, i));  // 4
printf("d offset: %zu\n", OFFSET_OF(struct Example, d));  // 8
printf("size: %zu\n", SIZE_OF(struct Example));           // 24

비트필드 (Bit-fields)

구조체 내에서 비트 단위 멤버 정의로 메모리 절약.

struct Flags {
    unsigned int ready : 1;
    unsigned int error : 1;
    unsigned int mode  : 2;  // 0~3
    unsigned int code  : 4;  // 0~15
    // 총 8비트 = 1바이트 (패딩 포함 보통 4바이트)
};

제약사항

유연한 배열 멤버 (Flexible Array Member, C99)

구조체 끝에 크기 미정 배열로 가변 길이 데이터 저장.

struct String {
    size_t len;
    char data[];  // 유연한 배열 멤버 (마지막 멤버만 가능)
};

// 할당
struct String *s = malloc(sizeof(struct String) + 100);
s->len = 5;
memcpy(s->data, "Hello", 6);  // 널 포함 복사

구조체와 함수

값 전달 vs 포인터 전달

// 값 전달 (복사본 수정)
void move_val(struct Point p, int dx, int dy) {
    p.x += dx; p.y += dy;
}

// 포인터 전달 (원본 수정)
void move_ptr(struct Point *p, int dx, int dy) {
    p->x += dx; p->y += dy;
}

// const 포인터로 읽기 전용
void print_point(const struct Point *p) {
    printf("(%d, %d)\n", p->x, p->y);
}

구조체 반환

struct Point midpoint(struct Point a, struct Point b) {
    return (struct Point){ (a.x+b.x)/2, (a.y+b.y)/2 };  // 복합 리터럴 반환
}

불완전 타입 (Incomplete Type) / 전방 선언

// 헤더 파일 (불완전 타입으로 포인터만 노출)
struct Opaque;  // 전방 선언
typedef struct Opaque Opaque;

Opaque *create();
void destroy(Opaque *);
void do_something(Opaque *);

// .c 파일에서 정의
struct Opaque {
    int hidden_data;
    double secret;
};

→ 정보 은닉, 컴파일 의존성 감소, ABI 안정성

모범 사례

C 언어

  1. C++ 구조체 vs 클래스: 임베디드 개발자를 위한 실용 가이드
  2. Nucleus RTOS의 세마포어: 유틸리티 서비스 및 데이터 구조
  3. 서평: '디지털라이즈 오어 다이(Digitise or Die)' – IoT 주도 트랜스포메이션 청사진
  4. 파괴적 기술 시대, 인간성 지키기
  5. 데이터 저장 혁명: 투명 망토 입은 차세대 자기 나노구조
  6. 2021년 코딩 실력 향상을 위한 최고의 프로그래밍 책 17권
  7. 자바 자료구조: 핵심 클래스와 컬렉션 프레임워크 탐구
  8. C typedef 완전 가이드: 타입 별칭, 구조체 간소화, 함수 포인터, #define과 차이
  9. C++ 데이터 구조: 배열, 구조체, 포인터로 효율적인 프로그램 만들기
  10. C# 구조체(Struct) 이해하기: 값 타입 정의와 사용법
연산자피연산자예시
.구조체 변수p1.x = 5;
->구조체 포인터p->x = 5; (≡ (*p).x)