728x90
UNION
C에서는 공용체라 부르는 특수한 타입이 있다. 공용체의 멤버로 선언된 변수들은 메모리 어드레스를 공유하게 된다. 어찌보면 별 필요없는 기능이라고 생각될 수도 있지만 메시지를 만들어 데이터를 읽고 쓰는데는 아주 유용한 기능이다.
선언 및 사용
union의 선언 방법은 struct와 동일하다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | union simple_message { int a; int b; }; int main( int argc, char **argv) { union simple_message smessage; smessage.a = 1; printf ( "smessage.a: %dn" , smessage.a); printf ( "smessage.b: %dn" , smessage.b); } |
출력 결과를 보면 공용체 smessage의 멤버 a의 값과 b의 값이 동일한 것을 볼 수 있다. 멤버 a의 값이 변경된 것이 b에도 적용된 것 처럼 보이지만 사실은 공용체 멤버 a와 b가 동일한 메모리 주소를 공유하고 있는 것이다.
Example
위와 같은 데이터를 읽고 쓴다고 하자. 4 bytes 데이터 이므로 int 값에 bit 연산으로 데이터를 채워 넣는 방법을 쓸 수도 있지만 가독성이 떨어지며 코드길이가 길어져 한참후에 코드를 들여다 봤을 때 이해하는 것이 불가능해 질 수도 있다. 하지만 union을 사용하면 데이터를 다루기도 쉽고 이해하기도 편리하다는 것을 깨닫게 될 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include <stdio.h> #include <linux/types.h> #include <memory.h> struct regdata { __u16 opcode:4; __u16 prtaddr:5; __u16 regaddr:5; __u16 ta:2; __u16 data; } __attribute__((packed)); union data { struct regdata reg0; __u32 rdata; }; int main( int argc, char ** argv) { union data message; memset (&message, 0x0, sizeof ( union data)); message.reg0.opcode = 0x4; message.reg0.regaddr = 0x3; message.reg0.data = 0xE8A3; printf ( "message: %08xn" , message.rdata); return 0; } |
실행결과는 message: e8a30604 이다. intel 시스템일 경우 little endian을 사용함으로 big endian으로 읽어보면 제대로데이터가 들어간 것을 알 수 있다.
728x90
'Program > C' 카테고리의 다른 글
[C] 연산자 정리 (0) | 2016.09.28 |
---|---|
[C] struct와 typedef struct의 차이점 (1) | 2016.09.26 |
[C] Enum 사용법 , C언어 열거형 사용법 열거형(Enum) (0) | 2016.09.26 |
[C] 전처리문의 종류(#include, #define, #ifdef, … ) (0) | 2016.09.26 |