공부했던 자료 정리하는 용도입니다.

재배포, 수정하지 마세요.

 

 

 

 

공용체(Union Type)

  공용체는 ``union`` 키워드를 사용해서 선언하며, 구조체와 선언방식은 비슷하지만 메모리에 할당되는 방식이 다르다. 구조체는 각각의 멤버가 메모리에 할당되지만 공용체는 멤버가 각각 할당되지 않고 크기가 가장 큰 멤버의 변수만 하나 할당되어 이를 공유하게 된다. 하나의 메모리 공간을 둘 이상의 방식으로 접근할 때 사용한다.

 

#include <stdio.h>

// 구조체
typedef struct sbox
{
	int mem1;
	int mem2;
	double mem3;
} Sbox;

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

int main(void)
{
	Sbox sbx;
	Ubox ubx;
	
	printf("구조체 : %p %p %p \n", &sbx.mem1, &sbx.mem2, &sbx.mem3);
	printf("공용체 : %p %p %p \n", &ubx.mem1, &ubx.mem2, &ubx.mem3);
	printf("Sbox size : %d\nUbox size : %d \n", sizeof(Sbox), sizeof(Ubox));
	
	return 0;
}

 

실행 결과

구조체는 각 멤버의 크기만큼 주소 값이 증가하는 반면,

공용체는 주소 값이 모두 같은 것을 확인할 수 있다.

 

구조체 변수와 공용체 변수의 차이점

그림으로 표현하면 위와 같다.

 

#include <stdio.h>

// 구조체 dbshort(DBShort) 정의 
typedef struct dbshort
{
	unsigned short upper;
	unsigned short lower;
} DBShort;

// 공용체 rdbuf(RDBuf) 정의 
typedef union rdbuf
{
	int iBuf;	 
	char bBuf[4];
	DBShort sBuf;	// DBShort형 구조체 변수를 멤버로 갖는다. 
} RDBuf;

int main(void)
{
	RDBuf buf;
	printf("정수 입력 : ");
	scanf("%d", &(buf.iBuf));
	
	printf("상위 2byte : %u \n", buf.sBuf.upper);
	printf("하위 2byte : %u \n", buf.sBuf.lower);
	printf("상위 1byte의 아스키코드 : %c \n", buf.bBuf[0]);
	printf("하위 1byte의 아스키코드 : %c \n", buf.bBuf[3]);
	
	return 0;
}

공용체의 특성을 이용해서 ``int``형 정수를 여러 가지 방식으로 접근하는 예시이다.

 

실행 결과
공용체 변수의 할당과 공유

공용체 변수 ``buf``는 메모리에서 위와 같은 형태로 할당되고 공유된다.

 

 

 

 

 


열거형(Enumerated Type)

enum syllable
{
	Do = 1, Re = 2, Mi = 3, Fa = 4, So = 5, La = 6, Ti = 7;
};

// 자료형을 생략한 형태로 열거형을 정의할 수도 있다.
enum {Do = 1, Re = 2, Mi = 3, Fa = 4, So = 5, La = 6, Ti = 7};

// 상수 값이 없을 경우 0부터 시작해서 1씩 증가하는 형태로 결정된다.(아래 두 문장은 같은 의미)
enum color {RED, BLUE, WHITE, BLACK};	
enum color {RED = 0, BLUE = 1, WHITE = 2, BLACK = 3};

// 중간에 값이 없으면 처음 값에서 1씩 증가한 값이 된다. (아래 두 문장은 같은 의미)
enum color {RED = 3, BLUE, WHITE = 6, BLACK};
enum color {RED = 3, BLUE = 4, WHITE = 6, BLACK = 7};

  열거형은 ``enum``키워드를 사용해서 선언하며, 구조체나 공용체와 마찬가지로 자료형을 정의하는 방법으로 사용된다. 구조체와 공용체는 자료형의 선언을 통해 멤버에 저장할 '값의 유형'을 결정하였다면 열거형의 경우에는 저장이 가능한 '값 자체'를 정수의 형태로 결정한다. 둘 이상의 연관있는 이름을 상수로 선언함으로써 프로그램의 가독성을 높이는 목적으로 사용된다. 변수의 선언이 목적이 아닌 상황에서는 자료형의 이름을 생략한 형태로 열거형을 정의하기도 하는데, 이렇게 하면 열거형 상수는 상수로써 의미를 지닌다.

 

  만약 위와 같이 ``syllable``이라는 열거형을 정의한다면 ``Do``, ``Re``, ``Mi``, ``Fa``, ``So``, ``La``, ``Ti``라는 이름의 상수를 각각 ``1``, ``2``, ``3``, ``4``, ``5``, ``6``, ``7``로 정의하고, 이 값들을 ``syllable``형 변수가 저장할 수 있는 값들로 제한한 것이다.

 

 

#include <stdio.h>

// 열거형 syllable(Syllable) 정의 
typedef enum syllable	// typedef 선언으로 enum syllable의 새로운 이름 Syllable 부여 
{
	Do = 1, Re = 2, Mi = 3, Fa = 4, So = 5, La = 6, Ti = 7
} Syllable;

void Sound(Syllable sy)
{
	switch(sy)
	{
		case Do:	// case 1: 도 가능 
			puts("도 입니다.");
			return;
		case Re:	// case 2: 도 가능
			puts("레 입니다.");
			return;
		case Mi:	// case 3: 도 가능
			puts("미 입니다.");
			return;
		case Fa:	// case 4: 도 가능
			puts("파 입니다.");
			return;
		case So:	// case 5: 도 가능
			puts("솔 입니다.");
			return;
		case La:	// case 6: 도 가능
			puts("라 입니다.");
			return;
		case Ti:	// case 7: 도 가능
			puts("시 입니다.");
			return;
	}
} 

int main(void)
{
	Syllable tone;	// 열거형인 Syllable형인 변수 tone 선언 
	for(tone = Do; tone <= Ti ; tone += 1)
		Sound(tone);
	
	return 0;
}

  열거형을 정의하고 사용하는 예시이다. 열거형 상수(enumeration constants)들은 ``int``형으로 표현되는 상수이기 때문에 주석부분처럼 ``case`` 레이블에 상수 ``Do``, ``Re``, ...을 대신해서 ``1``, ``2``, ...을 삽입해도 결과는 같다. 위의 예시의 경우 각각의 값이 음계와 관련된 것이기 때문에 열거형을 이용해서 프로그램의 가독성을 높인 것이다.

 

실행 결과

 

 

 

'기타 > C' 카테고리의 다른 글

[C] 매크로와 선행 처리기(Preprocessor)  (0) 2020.06.16
[C] 메모리 구조와 동적할당  (0) 2020.06.15
[C] 구조체  (0) 2020.06.01
[C] 문자, 문자열  (0) 2020.05.28
[C] 스트림, 버퍼  (0) 2020.05.27

+ Recent posts