Union 사용하여 little/big endian 확인.
이번 시간은 union(공용체)와 BitField에 대해서 알아보도록 하자.
예전에 번외편으로 Little Endian방식을 쓸때 구조체, union과 비트필드를 이용했다.
개별로는 많이 쓰이지 않기 때문에 이번시간에도 통틀어서 설명하겠다.
union에 대해서 간략하게 알아보자.
union은 공용체라고 불리운다.
선언 방식은 위의 코드처럼 전역으로 쓰이는 경우가 대부분이며, 구조체와 같은 형태를 가진다.
하지만 구조체와는 다른방식으로 데이터를 관리한다.
모든 공용체안의 멤버변수들은 같은 메모리 공간안에 자리를 잡고 쓰여지게 된다.
이걸 도식화해서 보기로 하자.
옆에 파란글씨고 써있는 부분이 도식화 할때 쓰인 코드다.
4Byte의 int형 iNum이란 변수 하나와 1Byte char형 ch란 변수
총 두개의 변수를 U란 공용체 안에 멤버로 선언했다.
메모리의 도식화는 저런 방식으로 된다.
공용체의 모든 멤버변수들은 같은 메모리의 공간을 공요하게 된다.
그래서 공용체의 크기는 제일큰 멤버변수의 DataType의 크기를 가지게 된다.
여기에서는 int형이 제일 커서 4Byte를 가진 공용체가 만들어 지는 것이다.
간략하게 공용체의 설명과 도식화를 보여드렸다.
자 이쯤에서 예제코드등장!
이제 이 소스코드를 보기로 하자.
제일 처음에 공용체 U를 선언했다 그리고 그 안에 구조체로 int형 변수 4개를 선언했다.
위의 코딩을 도식화 해보면 이렇게 나타나게 된다.
union안에는 Total이라는 int형 변수를 선언하고 구조체로 int형 변수를 4개 선언했다. 이때 주의할 점은, 구조체 안의 int형 변수는 각각 1Byte씩만 사용할수 있게 비트필드로 제한을 두었다. 비트필드란 변수의 특정비트만 사용할수 있게 만들수 있는 일종의 기법이다.
변수명 뒤에 " : 사용할 Bit수"를 적어주게 되면, 그에 해당하는 Bit만 사용할수 있게 된다. 여기서 보면 int형은 총 32Bit를 사용하지만 비트필드로 8Bit만 사용할수 있게끔 만들어 놓았다.
*BitField란! 하나의 메모리를 여러개의 Label을 붙여 쓰는것을 의미한다.
이게 뜻하는건 뭘까?
union안에 있는 Total이란 변수에 자료를 넣으면, 8Bit단위로 쉽게 꺼내올수 있다는걸 의미한다.
결과를 보도록 하자.
Ttotal 12345687를 넣었는데 union과 BitFIeld의 특성 때문에 1Byte씩 액세스 되는걸 볼수 있다.
숫자가 뒤집어 들어가는건 Little Endian때문인데, 그건 번외편을 보도록 하자.
공용체와 BitField는 이쯤에서 설명을 마치도록 하겠다.
많이 쓰이진 않지만, 주로 쓰이는 곳을 보자면, 위와 같은 특성때문에,
패킷연산이나, 고스톱알고리즘에 쓰이게 된다.
여기서 주의할점은 BitFiled가 진짜로 메모리에 어떻게 작용하는지 알려면,
#pragma pack(1)을 해주고 BitFiled가 정확히 메모리를 어떻게 쓰는지 알수 있다.
#pragma pack()의 기본 디폴트값은 4다.
예전에도 말했듯이 Intel CPU는 4Byte씩 메모리를 액세스 하기 때문에, 제대로된 내용을 파악하기 힘들다.
하지만 #pragma pack(1) 이것을 선언후에 하면 메모리 액세스를 1Byte씩 하게 된다.
그래서 정확한 BitField의 모습을 볼수 있다. 하지만, 액세스가 1Byte씩 일어나기 때문에, 전체적인
퍼포먼스가 떨어진다. 그래서 만약 실제 코딩때 쓴다면, 원래대로 #pragma pack(4), #pragma pack()
으로 돌려줘야 한다.
이쯤에서 이번장은 마치기로 하자.
뭔가 빨리 지나간 느낌이 있지만, 그만큼 드물게 쓰이기 때문에, 좀더 자세한 내용을 알고 싶다면,
따로 공부하시는걸 추천한다. 지금껏은 맛배기!
[출처] [C / C++]12장. union(공용체)와 BitField|작성자 련애린
'프로그래밍 > VC++ 개발 코딩' 카테고리의 다른 글
Visual Studio 2003을 비스타 및 Windows 7 에서 쓰기 (0) | 2014.01.17 |
---|---|
#pragma pack(push, 1), #pragma pack(pop) (0) | 2014.01.17 |
vector / CArray 사용하기 (0) | 2014.01.17 |
이중포인터 쓰고 지우기 (0) | 2014.01.17 |
fstream (ifstream, ofstream) (0) | 2014.01.17 |