임베디드 C 구조체 실전 가이드: 정의, 사용법, 메모리 최적화
구조체는 효율적인 임베디드 C 프로그래밍의 초석입니다. 이 글에서는 실제 응용, 선언 문법, 데이터 정렬이 메모리 사용에 미치는 영향을 탐구합니다. 구조체 멤버를 전략적으로 정렬하면 데이터 객체의 풋프린트를 줄일 수 있는데, 이는 리소스 제약 환경에서 중요한 고려사항입니다.
이 글은 임베디드 C에서 구조체에 대한 간결하면서도 포괄적인 개요를 제공합니다. 실제 응용, 올바른 선언 방법, 구조체 크기에 영향을 미치는 데이터 정렬의 미묘한 규칙을 다룹니다.
구조체
같은 타입의 여러 변수가 논리적 관계를 공유할 때 배열은 편리한 그룹화입니다. 예를 들어 음성 입력을 디지털화하는 ADC에서 최근 50개 샘플을 보관하려면:
uint16_t voice[50];
여기서 uint16_t는 stdint.h에 정의된 부호 없는 16비트 정수로, 플랫폼 간 일관된 크기를 보장합니다.
하지만 샘플 배열과 ADC의 샘플링 레이트처럼 다른 타입의 변수를 그룹화해야 한다면? 이들을 독립 변수로 별도 선언하면 불필요한 오버헤드가 발생합니다. 대신 구조체로 캡슐화할 수 있습니다:
struct record { uint16_t voice[50]; float sample_rate; };
record 구조체는 이제 uint16_t 배열과 float를 단일 논리적 연결 데이터 객체에 포함합니다.
구조체가 중요한 이유
구조체는 이질적인 변수를 응집력 있는 단위로 연관시켜 조작을 단순화하고 가독성을 높입니다. 임베디드 통신과 센서 데이터 처리에서 흔히 볼 수 있는 연결 리스트와 메시지 버퍼 같은 더 복잡한 데이터 구조의 기초가 됩니다.
예를 들어 마이크로컨트롤러의 메모리 매핑 주변장치는 하드웨어 레지스터 레이아웃을 반영하는 구조체로 표현되는 경우가 많아 멤버 문법으로 간편하게 레지스터에 접근할 수 있습니다.

그림 1. 구조체로 연결 리스트 구현 가능.

그림 2. STM32 MCU 메모리 맵. Embedded Systems with ARM 제공.
구조체 선언
먼저 구조체 템플릿을 정의합니다. 다음 예제를 고려하세요:
struct record { uint16_t voice[4]; float sample_rate; };
템플릿 자체는 메모리를 소비하지 않으며, 해당 타입의 변수를 선언할 때만 할당됩니다:
struct record mic1;
이제 mic1은 네 개의 uint16_t 요소와 하나의 float을 위한 충분한 공간을 차지합니다. 점 연산자로 멤버에 접근:
mic1.voice[0] = 100; float fs = mic1.sample_rate;
구조체 선언의 다른 방법
가장 일반적인 패턴은 구조체를 먼저 정의하고 변수를 선언하는 것이지만, C는 대체 문법을 제공합니다:
문법 1: 태그와 변수 동시 선언
struct record { uint16_t voice[4]; float sample_rate; } mic1;
이후 변수는 별도 선언 가능:
struct record mic2;
문법 2: 익명 템플릿
struct { uint16_t voice[4]; float sample_rate; } mic1;
이름이 없으므로 템플릿을 다른 곳에서 재사용할 수 없습니다.
문법 3: 익명 중첩 구조체
struct test { struct { float f; char a; }; } test_var;
내부 멤버에 직접 접근:
test_var.f = 1.2f;
익명 구조체는 장황함을 줄이지만 명확성을 위해 신중히 사용해야 합니다.
구조체 메모리 레이아웃
C 표준은 멤버가 선언 순서대로 순차적으로 메모리에 배치됨을 보장합니다. 예:
struct Test2 { uint8_t c; uint32_t d; uint8_t e; uint16_t f; } MyStruct;
32비트 머신에서 sizeof(MyStruct)는 uint32_t를 4바이트 경계에 정렬하기 위한 패딩으로 인해 12바이트입니다. 멤버 재정렬로 패딩을 제거할 수 있습니다:
struct Test2 { uint32_t d; uint16_t f; uint8_t c; uint8_t e; } MyStruct;
이제 sizeof(MyStruct)는 8바이트로 줄어듭니다—메모리 제약 펌웨어에서 귀중한 절약입니다.

그림 3. 데이터 정렬이 구조체 메모리 레이아웃에 패딩을 추가할 수 있음.
요약
- 구조체로 이질적 변수를 단일 관리 단위로 묶어 코드 명확성과 효율성 향상.
- 커스텀 데이터 구조로 장치 간 메시징과 센서 데이터 저장 지원.
- 메모리 매핑 주변장치의 하드웨어 레지스터 매핑에 필수.
- 정렬을 고려한 멤버 재정렬로 구조체 크기 크게 줄일 수 있음.
더 많은 임베디드 C 튜토리얼을 여기서 탐색하세요.