공용체
멤버 변수끼리 같은 메모리 공간을 공유하는 형태
- 공용체의 각 멤버들의 메모리 시작 주소는 모두 동일하다. ▶ 각 멤버 변수의 변화가 다른 멤버 변수에 영향을 줌
- 반면, 구조체는 멤버 변수가 각각 다른 메모리 공간을 할당 받음
- 그다지 사용빈도가 높지 않은 기능
공용체 구현
- struct 대신 union을 적으면 된다.
union 공용체이름 {
/*멤버들*/
int age;
string name;
};
공용체 구현 예제
#include <iostream>
#include <sstream>
using namespace std;
union uni {
int a;
char b;
};
int main() {
union uni A;
A.a = 0x12345678; // 16진수
cout << "A.b: " << A.b << endl;
cout << "0x" << hex << int(A.b) << endl;
return 0;
}
A.b: x
0x78
- A.b 값을 초기화하지 않았음에도 A.b를 출력할 수 있었다.
- 위의 경우에서는 메모리에 다음과 같이 저장된다.
- char와 int는 시작 주소를 공유하면서 메모리에 할당되어 있다.
- 그런데 int에 0x12345678를 대입하였음에도 char에는 12가 아닌 78이 저장되었다.
- 이는 컴퓨터의 수 보관 체계에 따른 결과이다.
빅 엔디안(Big Endian), 리틀 엔디안(Little Endian)
- 컴퓨터에서 메모리에 수를 저장하는 방법은 빅 엔디안 방식, 리틀 엔디안 방식 총 2개로 나뉜다.
- 엔디안(Endian): 컴퓨터의 메모리와 같은 1차원의 공간에 여러 개의 연속된 대상을 배열하는 방법
빅 엔디안(Big Endian)
- 낮은 주소에 데이터의 높은 바이트(MSB, Most Significant Bit)부터 저장하는 방식
- 메모리에 저장된 순서 그대로 읽을 수 있기 때문에 이해가 쉽다는 장점이 있다. ▶ 우리가 평소에 수를 읽는 방식
- 네트워크를 통해 데이터를 전송할 때 빅 엔디안 방식이 사용된다. ▶ MSB를 우선 보내고, 후에 LSB를 전송
- 따라서 빅 엔디안에서 0x12345678은 다음과 같이 저장된다.
리틀 엔디안(Little Endian)
- 낮은 주소에 데이터의 낮은 바이트(LSB, Least Significant Bit)부터 저장하는 방식
- 우리가 수를 읽는 방식과 반대로 읽는다.
- 컴퓨터가 데이터를 계산하는데 리틀 엔디안 방식이 유리하다. ▶ 낮은 바이트의 데이터를 먼저 계산해야 carry의 발생을 고려하는데 더욱 유리함
- x86 아키텍처(인텔)가 리틀 엔디안 방식을 사용하며, 우리가 사용하는 대부분(99%)의 컴퓨터는 리틀 엔디안이다.
- 따라서 리틀 엔디안에서 0x12345678은 다음과 같이 저장된다.
- 리틀 엔디안 방식에서 메모리의 시작주소는 78 데이터를 가리키고 있으며, 이것이 A.b의 값이 0x78이 된 이유이다.
Ex) short(2bytes)와 int(4bytes)
#include <iostream>
#include <sstream>
using namespace std;
union uni {
int a;
short b;
};
int main() {
union uni A;
A.a = 0x12345678;
cout << "A.a > 0x" << hex << A.a << endl;
cout << "A.b > 0x" << hex << A.b << endl;
return 0;
}
A.a > 0x12345678
A.b > 0x5678
- short는 2bytes를 차지하기 때문에 리틀 엔디안 방식에서는 0x78과 0x56을 모두 포함한다.
- 따라서 A.b는 0x7856이 나올 것 같지만, 0x5678가 나왔다.
- 이는 컴퓨터가 리틀 엔디안으로 동작함을 알고 있어 적절한 변환을 통해 0x5678을 출력하였기 때문이다.
- A.a가 0x12345678로 출력된 것 또한 같은 이유이다.