제 25강) 공용체와 열거형 |
오늘은 공용체(union)와 열거형(enum)에 대해서 알아보도록 합니다.
1) 공용체(union) |
공용체의 사용법 자체는 구조체(struct)와 비슷합니다만 한 가지 다른 점이 있습니다.
// 사용법
union 공용체_이름 {
자료형 변수이름;
자료형 변수이름;
...
};
// 예)
union Person {
char* name;
int age;
char sex;
};
구조체 처럼 선언을 하고 사용하게 됩니다만 위에서 언급한대로 한 가지 다른 점이 있습니다.
바로 공용체는 내부의 자료들이 메모리를 공유한다는 것이지요.
#include <stdio.h>
struct STRUCT1
{
double d_num;
int i_num;
char ch;
}
union UNION1
{
double d_num;
int i_num;
char ch;
}
이렇게 구조체와 공용체가 선언이 되면 메모리는
이렇게 생성이 됩니다.
구조체의 경우에는 구조체 내부에 선언된 변수에 맞게 각각의 메모리 공간을 할당하지만
공용체의 경우에는 가장 최상단의(가장 큰) 변수에 맞게 메모리 공간을 할당한 후에 나머지 변수는 자신의 크기만큼 맨 앞 주소부터 생성이 됩니다.
그러므로 공용체로 선언하면 "공유되는 구간"이 생기게 됩니다.
이것을 눈으로 직접 확인하여 봅시다.
위의 내용이 맞다면 제일 큰 변수에 값을 넣어주면 그 값의 일부가 나머지에도 들어간다는 소리이니까요.
#include <stdio.h>
union UNION1
{
int i_num;
short s_num;
char ch;
};
int main(void)
{
union UNION1 u;
u.i_num = 0x12345678;
printf("i_num: %x\n", u.i_num);
printf("s_num: %x\n", u.s_num);
printf("ch: %x\n", u.ch);
return 0;
}
이것을 확인하기 위한 예제입니다.
UNION1 공용체에는 4바이트 변수 i_num, 2바이트 변수 s_num, 1바이트 변수 ch가 선언되어있습니다.
최상단의 변수 i_num에 0x12345678을 저장하여 16진수 그대로 각각의 변수들을 출력하는 예제입니다.
결과를 보면 납득하기가 어려울 수 있습니다.
이럴것이라고 생각하셨을 수 있기 때문입니다.
이렇게 저장되는 것은 "빅 엔디안(Big Endian)" 방식이라고 합니다.
하지만 대다수의 컴퓨터는
이렇게 빅 엔디안이 아닌 "리틀 엔디안(Little Endian)"방식으로 저장됩니다.
그럼 이 공용체는 왜 쓰일까요?
바로 메모리를 절약하는데 쓰입니다.
union UNION1
{
int i_num;
short s_num;
char ch;
};
최 상단의 i_num이 사용되지 않는다고 하면 나머지 s_num 또는 ch가 그 공간을 사용 할 수 있게됩니다.
i_num을 사용하든지, s_num을 사용하던지, ch를 사용하던지 똑같이 메모리는 4바이트만큼을 할당하게 됩니다.
struct STRUCT1
{
int i_num;
short s_num;
char ch;
};
하지만 구조체를 사용하는 경우에는 어떤 경우이던간에 4바이트 + 2바이트 + 1바이트인 7바이트를 사용하게 되는 것이지요.
그래서 통신 프로토콜에 많이 사용한다고 합니다.
2) 열거형(enum) |
열거형은 정말 자주 사용하고 유용한 것입니다.
// 선언
enum
{
식별자1, 식별자2, ... , 식별자n
};
// 예)
enum
{
None, Programmer, Doctor, Teacher, Salesman
};
이렇게 선언하여 사용합니다.
(보통 enum내에 오는 식별자의 이름은 "대문자"로 해줍니다.)
위의 예를 보면 대충 감이 오실수도 있는데 열거형은 무언가를 식별할 때 유용하게 사용합니다.
int selector;
switch (selector)
{
case 의사일때:
....
case 프로그래머일때:
....
case 선생님일때:
....
.......
default: // 직업이 없을때
....
}
이렇게 무언가를 식별해야할 때 사용하면 유용한 것이지요.
위에서 예로 본 Job을 위의 예제에 덫붙이면
enum
{
None, Programmer, Doctor, Teacher, Salesman
};
int selector;
switch (selector)
{
case Doctor:
....
case Programmer:
....
case Teacher:
....
.......
default: // 직업이 없을때
....
}
이렇게 바뀌는 것이지요.
여기서 enum 내에 선언되는 값들은 순차적인 값을 가지게 됩니다.
enum
{
None, Programmer, Doctor, Teacher, Salesman
// 0, 1, 2, 3, 4
};
맨 앞을 기준으로 0, 1, 2, 1씩 증가하게 됩니다.
그러나 값을 지정해 줄 수 있습니다.
enum
{
None = 5, Programmer = 11, Doctor = 3, Teacher = 142, Salesman = 0
};
이렇게 원하는 값을 넣어주면 됩니다.
그런데 넣어줄 수 있는 값은 오직 "Integer, 정수값(상수)"만 넣을 수 있습니다.
(C언어 표준 6.7.2.2 Enumeration specifiers에 "The expression that defines the value of an enumeration constant shall be an integer constant expression that has a value representable as an int." 라고 명시되어 있습니다.)
또한 enum은
enum
{
None = 5, Programmer, Doctor, Teacher = 142, Salesman
};
이렇게 선언되어 있다면 다음 값이 새로 선언되기 전까지 1씩 증가하게 됩니다.
enum
{
None = 5, Programmer, Doctor, Teacher = 142, Salesman
// 5, 6, 7, 142, 143
};
이렇다는 말입니다.
이제 이 enum을 가지고 게임 캐릭터 생성 예제를 만들어봅시다.
#include <stdio.h>
enum
{
WARRIOR = 1, THIEF, WIZARD, GUNNER, MERCHANT
};
int main(void)
{
char name[20] = { 0, };
int job;
printf("======캐릭터 생성======\n");
printf("닉네임: ");
scanf("%[^\n]s", name); // 띄어쓰기 포함
while (getchar() != '\n'); // 입력버퍼 비우기(엔터)
printf("1. 전사, 2. 도적, 3. 마법사, 4. 거너, 5. 상인\n");
printf("선택: ");
scanf("%d", &job);
printf("\n");
printf("======캐릭터 생성 결과======\n");
printf("닉네임: %s\n", name);
printf("직업: ");
switch (job)
{
case WARRIOR:
printf("전사\n");
break;
case THIEF:
printf("도적\n");
break;
case WIZARD:
printf("마법사\n");
break;
case GUNNER:
printf("거너\n");
break;
case MERCHANT:
printf("상인\n");
break;
}
return 0;
}
enum을 사용하여 switch 문을 식별하는 예제입니다.
다음 시간에는 |
다음 시간에는 파일 입출력에 대해서 알아보겠습니다.
'Study > C언어' 카테고리의 다른 글
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 27 [C언어의 파일 입출력2] (0) | 2018.10.28 |
---|---|
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 26 [C언어의 파일 입출력1] (0) | 2018.10.28 |
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 23 [메모리 구조와 메모리 할당, 배열 동적할당(malloc, realloc, calloc, free)] (0) | 2018.10.28 |
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 24 [구조체와 형식 정의 지정자(struct, typedef)] (0) | 2018.10.28 |
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 21 [다차원배열1 - 다차원배열의 기본(2차원, 3차원)] (0) | 2018.10.17 |