본문 바로가기
Language&Framework&Etc/C

구조체와 사용자 정의 자료형2(23-4) 공용체(Union Type)의 정의와 의미

by 머리올리자 2020. 12. 13.

구조체 : struct

공용체 : union

구조체 vs 공용체

#include <stdio.h>

// 구조체 Spoint의 정의
typedef struct spoint 
{
	int mem1;
	int mem2;
	double mem3;

}Spoint;

// 공용체 Upoint의 정의
typedef union upoint 
{
	int mem1;
	int mem2;
	double mem3;

}Upoint;

정의방식의 유일한 차이점은 struct 선언을 하느냐, union 선언을 하느냐에 차이

그러나 각각의 변수가 메모리 공간에 할당되는 방식과 접근의 결과에는 많은 차이가 있다.

 

printf("%d \n", sizeof(Spoint)); // 16 출력
printf("%d \n", sizeof(Upoint)); // 8 출력

16은 모든 멤버의 크기를 합한 결과이고,

8은 멤버 중에서 가장 크기가 큰 double의 크기만 계산

 

예제.

#include <stdio.h>

// 구조체 Spoint의 정의
typedef struct upoint 
{
	int mem1;
	int mem2;
	double mem3;

}Spoint;

// 공용체 Upoint의 정의
typedef union spoint 
{
	int mem1;
	int mem2;
	double mem3;

}Upoint;

int main(void)
{
	Spoint sp;
	Upoint up;

	printf("%p %p %p \n", &sp.mem1, &sp.mem2, &sp.mem3);
	printf("%p %p %p \n", &up.mem1, &up.mem2, &up.mem3);
	printf("%d %d \n", sizeof(sp), sizeof(up));
	return 0;
}

보면 up형 변수를 구성하는 멤보 mem1, mem2, mem3의 주소 값이 동일하다는 사실.

 

이는 공용체의 다음과 같은 할당 특성

구조체 변수

 

공용체 변수

위 그림에서 보이듯이 구조체 변수가 선언되면, 구조체를 구성하는 멤버는 각각 할당이 된다.

 

반면 공용체 변수가 선언되면, 공용체를 구성하는 멤버는 각각 할당되지 않고, 그 중 크기가 가장 큰 멤버 변수만 하나 할당되어 이를 공유

 

예제

#include <stdio.h>

typedef union ubox // 공용체 ubox의 정의
{
	int mem1;
	int mem2;
	double mem3;
} Ubox;

int main(void)
{
	Ubox ub;
	ub.mem1 = 20; // 4바이트 메모리 공간에 20 저장
	printf("%d \n", ub.mem2); // mem2는 int형 변수 -> 접근할 경우 4바이트의 메모리 공간 참조 -> 20 출력

	ub.mem3 = 7.15; // 실수 저장, 값을 덮어써버림
	printf("%d \n", ub.mem1); // 4바이트를 읽어서 출력하면 알 수 없는 값
	printf("%d \n", ub.mem2);
	printf("%g \n", ub.mem3);
	return 0;
}

메모리 공간을 공유하고 있음을 확인.

 

이런 공용체는 어떨 때 쓰임?

 

공용체의 유용함은 다양한 접근방식을 제공하는데 있다.

공용체의 유용함은 '하나의 메모리 공간을 둘 이상의 방식으로 접근할 수 있다'는 것으로 정리가 되지만, 유용하게 사용이 되는 상황은 분야별로 약간씩 차이가 있다.

 

예시

 

프로그램 사용자로부터 int형 정수 하나를 입력 받음

입력 받은 정수의 상위 2바이트와 하위 2바이트 값을 양의 정수로 출력

상위 1바이트와 하위 1바이트에 저장된 값의 아스키 문자 출력

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

typedef struct dbshort
{
	unsigned short upper; // 2바이트
	unsigned short lower; // 2바이트
}DBShort;

/* 공용체 4바이트 크기 할당*/
typedef union rdbuf
{
	int iBuf; // 4바이트 전체 
	char bBuf[4]; // 1바이트 씩
	DBShort sBuf; // 구조체 변수
}RDBuf;

int main(void)
{
	RDBuf buf;
	printf("정수 입력 : ");
	scanf("%d", &(buf.iBuf));

	printf("상위 2바이트: %u \n", buf.sBuf.upper);
	printf("하위 2바이트: %u \n", buf.sBuf.lower);
	printf("상위 1바이트 아스키 코드: %c \n", buf.bBuf[0]);
	printf("하위 1바이트 아스키 코드: %c \n", buf.bBuf[3]);
}

위 예제에 선언된 공용체 변수는 메모리 공간에 다음의 형태로 할당되고 공유가 된다.

 

참고 : [윤성우 열혈 C 프로그래밍] - 대부분의 내용 및 코드는 이 책에서 개인 공부 정리 목적으로 참고하였습니다.