Union 은 C 언어에서 서로 다른 데이터 타입을 하나의 메모리 공간에서 저장할 수 있게 하는 키워드이다. 이는 구조체(struct)와 비슷하지만, Union 내의 모든 멤버가 같은 메모리 주소를 공유한다는 점에서 차이가 있다. 결과적으로, 한 시점에 하나의 멤버만 저장하고 사용할 수 있으며, 가장 큰 크기의 멤버에 의해 union의 전체 크기가 결정된다. 이를 통해 메모리를 효율적으로 사용할 수 있지만, 멤버 간에 값의 오버라이트가 발생할 수 있다는 점을 유의해야 한다.
⭐1. Union 사용법
#include <stdio.h>
union Data {
int i;
float f;
char str[20];
};
int main() {
union Data data;
data.i = 10;
printf("data.i : %d\n", data.i);
data.f = 220.5;
printf("data.f : %f\n", data.f);
sprintf(data.str, "%s", "C Programming");
printf("data.str : %s\n", data.str);
return 0;
}
이 예제에서 union Data는 정수(int), 부동 소수점(float), 문자열(char[]) 중 하나를 저장할 수 있다. union을 사용하면 세 가지 타입 중 하나만 메모리에 저장되고, 가장 최근에 저장된 값만 유효하게 된다. 이는 모든 멤버가 동일한 메모리 주소를 공유하기 때문이다. 이 코드를 실행하면, 마지막에 저장된 값인 문자열 "C Programming"만 올바르게 출력되며, 다른 필드는 오버라이트된다.
즉, 모든 멤버가 동일한 주소를 공유하기 때문에 값을 대입할 때 마다 모든 값들이 갱신된다는 것을 알 수 있다. 그렇다면 Union은 어떤 상황에서 쓸 수 있는가?
⭐2. UNION 공용체와 STRUCT 구조체로 패킷 만들기
대표적으로 통신 분야로 가장 많이 사용된다. 통신에서는 데이터를 송신하는 것도 중요하지만, 데이터를 수신해서 제대로 해석하는 것도 굉장히 중요하다. 구조체와 공용체를 적절히 사용하면 하기와 데이터 송수신 예제를 만들 수 있다.
#include <stdio.h>
#include <stdint.h>
// Struct Packet_s 선언
typedef struct packet_s
{
uint8_t data0;
uint8_t data1;
uint8_t data2;
uint8_t data3;
}Packet_s;
typedef union packet_u
{
Packet_s ps; // Struct Packet_s ps 정의 // 송신
uint8_t pu[4]; // 수신
}Packet_u;
int main()
{
Packet_u packet_data;
packet_data.ps.data0 = 0; // 예를 들어 uuid
packet_data.ps.data1 = 1; // minor
packet_data.ps.data2 = 2; // tx power
packet_data.ps.data3 = 3; // rssi
printf("pacekt_data size = %d bytes\n\n", sizeof(packet_data));
printf("송신 사이즈 : %d bytes\n\n", sizeof(packet_data.ps));
printf("------송신 준비 완료------\n");
printf("--------------------------\n");
printf("--------------------------\n");
printf("-------송수신 완료--------\n\n");
printf("수신 사이즈 : %d bytes\n", sizeof(packet_data.pu));
printf("uuid = %d\n", packet_data.pu[0]);
printf("minor = %d\n", packet_data.pu[1]);
printf("tx power = %d\n", packet_data.pu[2]);
printf("rssi = %d\n", packet_data.pu[3]);
return 0;
}
이 코드는 C 언어로 작성된 소프트웨어에서 데이터 패킷을 표현하고 처리하는 방법을 보여준다. struct packet_s는 4개의 uint8_t 데이터 필드를 가지고 있어, 각각의 필드가 패킷의 한 부분을 나타낸다. 이 구조체는 union packet_u 내에서 ps라는 이름으로 정의되어 있다. 동일한 union 내에 uint8_t 타입의 배열 pu[4]도 정의되어 있어, 송신 시 ps를 통해 각 필드를 개별적으로 설정할 수 있고, 수신 시 pu 배열을 통해 전체 데이터를 연속된 바이트로 처리할 수 있다. 이는 메모리 효율성을 극대화하며, 데이터를 유연하게 접근할 수 있게 해준다.
'C언어 30강' 카테고리의 다른 글
[C/C++ Tip] 8. 배열과 포인터 (0) | 2024.09.07 |
---|---|
[C/C++ Tip] 7. 배열의 기초 (1) | 2024.09.04 |
[C/C++ Tip] 5. 구조체 패딩의 필요성 (0) | 2024.09.04 |
[C/C++ Tip] 4. 구조체 활용: 효율적인 데이터 관리 (2) | 2024.09.02 |
[C/C++ Tip] 3. 코딩 규칙. 변수명 정하기 (0) | 2024.09.01 |