나의 IT일지
공용체 본문
구조체는 여러 자료형의 변수를 저장하여 만든 자료형으로, 변수마다 할당되는 저장공간이 존재한다. 이러한 변수는 정해놓은 필드를 토대로 값을 저장할 수 있는 형태이다.
그리고 구조체처럼 필드를 정해놨지만, 하나의 필드 값이 변하면 다른 필드 값이 변하는 자료형이 있는데, 이를 공용체라고 한다.
공용체
공용체란, 하나의 메모리공간을 여러개의 변수가 공용해서 사용하도록 만든 자료형으로, 해당 자료형을 통해 변수를 생성하면, 하나의 값으로 모든 필드의 값을 정할 수 있게 된다.
공용체 선언방법(필드 생성 방법) | 공용체 변수 생성 방법 |
union 공용체명{ 자료형 변수명1;//필드1 자료형 변수명2;//필드2 ... } |
union 공용체명 변수명; |
위는 공용체를 선언하는 방법과 변수를 생성하는 방법으로, 자료형과 같은 형태를 가지고 있다.
이때, union은 예약어로, 공용체 선언이 끝나고 공용체명과 함께 사용하면 공용체형이라는 새로운 자료형이 된다. 즉,공용체선언을 통해 필드의 구성을 저장하며, 생성할려는 변수의 형태를 정의하는 자료형으로, 공용체형이라고 한다.
필드 생성하는 방법은 "union 구조체명"을 정의하는 것으로, 틀을 만들고 그 안에 데이터를 저장 할 수 있는 필드의 공간을 만들어 자료형을 정의한다. 그리고 공용체 변수 생성방법에서는 공용체 선언에서 정의한 틀을 기준으로, 속성 데이터를 저장할 수 있는 공간을 만든다.
#include<stdio.h>
union data{
char ch;
int num;
double lo_num;
};
void main() {
union data u_data;
printf("union sizeof(u_data):%d\n", sizeof(u_data));
}
위의 결과를 보면, 공용체형을 이용하여 만든 변수의 메모리 공간이다. 구조체형과 달리 "double"형의 저장공간만 가지고 있는것을 알 수 있는데, 이는 필드 중에서 가장 큰 변수의 byte크기만큼 생성된다는 것을 알 수 있다. 즉 구조체는 필드에 따라 메모리공간을 할당하지만, 공용체는 모든 필드가 하나의 메모리 공간을 같이 사용한다는 것이다.
구조체와 공용체의 메모리공간 할당을 정리하자면 다음과 같다.
만약 아래의 코드와 같이 구조체형 "a"이 설정되었을 경우, 구조체형로 만든 변수는 그림과 같은 메모리공간이 할당된다.
struct a{
int a;
double b;
char c;
};
그리고 만약 아래와 같이 공용체형 "a"이 설정되었을 경우, 공용체형로 만든 변수는 그림과 같은 메모리공간이 할당된다.
union a{
int a;
double b;
char c;
};
#include<stdio.h>
union data {
char ch;
int num;
long lo_num;
};
void main() {
union data u_data;
u_data.lo_num = 409612865;
printf("u_data.ch:%c\n", u_data.ch); //아스키코드로 변환
printf("u_data.num:%d\n", u_data.num);
printf("u_data.lo_num:%d\n", u_data.lo_num);
}
u.data의 레코드에 접근할 때, "u_data.필드명"을 사용하는 것을 볼 수 있다. 즉, 변수의 내용(레코드)에 접근할 때의 형태는 "변수명.필드명"이다.
그리고 "lo_num" 필드에만 데이터를 저장을 했는데, 다른 필드에도 데이터가 있는 것을 확인 할 수 있다. 이는 같은 메모리 공간을 사용해서 나타나는 현상인데, 메모리 공간에 데이터가 저장이 되어 있고, 그 데이터를 자료형에 맞춰서 출력이 되는 것이다. 그래서 문자형 변수인 "ch"변수는 아스키코드가 "65"인 "A"가 출력이 되는 것이다.
공용체와 배열
구조체와 마찬가지로 공용체의 필드로 배열을 사용할 수 있으며, 아래의 구조를 갖는다면 그림과 같이 메모리 공간이 배정된다.
union data
{
int b;
char c[2];
};
이를 이용해서 코드를 작성하고 결과를 출력하면, 다음과 같이 나온다.
#include<stdio.h>
union data
{
short int num;
char ch[2];
};
void main() {
union data data_1;
data_1.ch[0] = 'A';
data_1.ch[1] = 'B';
printf("data1.ch[0]= %d\n", data_1.ch[0]);
printf("data1.ch[1]= %d\n", data_1.ch[1]);
printf("data1.num= %d\n", data_1.num);
}
위의 결과를 보면 배열에 값을 저장을 저장을 했지만, 정수형 변수에도 값이 출력되는것을 볼 수 있다. 이는 배열의 값을 메모리공간이 가지고 있다는 것이다.
즉, "A"의 아스키 코드는 "65"이며 이를 이진수로 바꾸면 "0100 0001"이고, "B"의 아스키 코드는 "66"이며 이를 이진수로 바꾸면 "0100 0010"이 되므로, 정수형 변수에는 "0100 0010 0100 0001"이라는 데이터가 저장되어 있는것이며, 이를 십진수로 변형하면 "16961"이 된다.