๐Ÿ“˜16์žฅ Structures, Unions, and Enumerations | Study

ํŒŒ์ธยท2022๋…„ 1์›” 30์ผ
0

C

๋ชฉ๋ก ๋ณด๊ธฐ
7/9
post-thumbnail

C Programming, A Modern Approach - K.N.KING์œผ๋กœ C์–ธ์–ด๋ฅผ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.
๋ฒˆ์—ญ๋ณธ https://wikidocs.net/book/2494 ์„ ์ฐธ๊ณ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.



16.1 Structure Variables
16.2 Structure Types
16.3 Nested Arrays and Structures
16.4 Unions
16.5 Enumerations



๐Ÿ“ Structures, Unions, and Enumerations

๊ตฌ์กฐ์ฒด : ์„œ๋กœ ๋‹ค๋ฅธ ํ˜•์„ ๊ฐ€์งˆ ์ˆ˜๋„ ์žˆ๋Š” ๊ฐ’(๊ตฌ์„ฑ์›)์˜ ์ง‘ํ•ฉ
๊ณต์šฉ์ฒด : ๊ตฌ์กฐ์ฒด์™€ ์œ ์‚ฌํ•˜๋‚˜ ๊ฐ ๊ตฌ์„ฑ์›์ด ๊ฐ™์€ ์ €์žฅ ๊ณต๊ฐ„์„ ๊ณต์œ , ๊ทธ๋ ‡๊ธฐ์— ๊ณต์šฉ์ฒด๋Š” ํ•œ ๋ฒˆ์— ๋™์‹œ์— ๋ชจ๋“  ๊ตฌ์„ฑ์›์„ ์ €์žฅํ•  ์ˆ˜ ์—†๊ณ , ํ•œ ๊ตฌ์„ฑ์›๋งŒ์„ ์ €์žฅ
์—ด๊ฑฐํ˜• : ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๋ช…๋ช…ํ•œ ๊ฐ’์œผ๋กœ ๋œ ์ •์ˆ˜ํ˜•


๐Ÿ“ Structure Variables

๊ตฌ์กฐ์ฒด์˜ ์›์†Œ(member)๋Š” ๊ฐ™์€ ํ˜•์ผ ํ•„์š”๊ฐ€ ์—†๋‹ค.
๊ตฌ์กฐ์ฒด์˜ ๊ตฌ์„ฑ์›๋“ค์—๊ฒ ์ด๋ฆ„์ด ์กด์žฌํ•˜์—ฌ ํŠน์ • ๊ตฌ์„ฑ์›์„ ์„ ํƒํ•˜๋ ค๋ฉด ์œ„์น˜๊ฐ€ ์•„๋‹Œ ์ด๋ฆ„์„ ํŠน์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.


๐Ÿ“ Declaring Structure Variables

๐Ÿ”Ž ๋ถ€ํ’ˆ ๋ฒˆํ˜ธ, ๋ถ€ํ’ˆ ์ด๋ฆ„, ๋ถ€ํ’ˆ ๊ฐœ์ˆ˜ ์ €์žฅํ•˜๊ธฐ

struct {
	int number;
	char name[NAME_LEN + 1];
	int on_hand;
} part1, part2;

๊ตฌ์กฐ์ฒด์˜ ๊ตฌ์„ฑ์›(member) : number, name, on_hand
ํ˜• : struct
๋ณ€์ˆ˜ : part1, part2

NAME_LEN์˜ ๊ฐ’์ด 25๋ผ๊ณ  ํ•˜๋ฉด, ๋ณ€์ˆ˜ part1์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋œ๋‹ค.

๊ฐ ๊ตฌ์กฐ์ฒด๋Š” ์ƒˆ๋กœ์šด ์Šค์ฝ”ํ”„๋ฅผ ๊ฐ–๋Š”๋‹ค. C ์šฉ์–ด๋กœ ๋งํ•˜๋ฉด ๊ฐ ๊ตฌ์กฐ์ฒด๋Š” ๊ตฌ์„ฑ์›๋“ค์— ๋Œ€ํ•ด ์„œ๋กœ ๋‹ค๋ฅธ ์ด๋ฆ„ ๊ณต๊ฐ„ (namespace)๋ฅผ ๊ฐ–๋Š”๋‹ค๊ณ  ํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜์™€ ๊ฐ™์ด ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค.

struct {
	int number;
	char name[NAME_LEN + 1];
	int on_hand;
} part1, part2;

struct {
	char name[NAME_LEN + 1];
	int number;
	char sex;
} employee1, employee2;



๐Ÿ“ Initializing Structure Variables

๐Ÿ”Ž ๊ตฌ์กฐ์ฒด ์„ ์–ธ ์‹œ์— ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ

struct {
	int number;
	char name[NAME_LEN + 1];
	int on_hand;
} part1 = { 528, "Disk drive", 10 }, 
part2 = { 914, "Printer cable", 5 };

์ดˆ๊ธฐํ™”ํ•  ๊ตฌ์กฐ์ฒด์˜ ๊ตฌ์„ฑ์› ์ˆ˜๋ณด๋‹ค ์ ์€ ์ˆ˜์˜ ์ดˆ๊ธฐ์ž๊ฐ€ ์ฃผ์–ด์งˆ ๊ฒฝ์šฐ ๋‚˜๋จธ์ง€ ์ดˆ๊นƒ๊ฐ’์€ 0์ด ๋œ๋‹ค. ํŠนํžˆ ๋ฌธ์žํ˜• ๋ฐฐ์—ด์˜ ๋‚˜๋จธ์ง€ ๋ฐ”์ดํŠธ๋“ค์€ 0์ด ๋˜์–ด ๋น„์–ด์žˆ๋Š” ๋ฌธ์ž์—ด์ด ๋œ๋‹ค.




๐Ÿ“ [C99] Designated Initializers

๐Ÿ”Ž ์ง€์ • ์ดˆ๊ธฐ์ž

{.number = 528, .name = "Disk drive", .on_hand = 10}

์ง€์ •์ž(designator) : ๊ตฌ๋‘์ (.) + ๊ตฌ์„ฑ์› ์ด๋ฆ„

๐Ÿ”Ž ์ง€์ • ์ดˆ๊ธฐ์ž์˜ ์žฅ์ 

1) ๊ตฌ์กฐ์ฒด์˜ ๊ตฌ์„ฑ์›๊ณผ ์ดˆ๊ธฐ์ž ๊ฐ’์˜ ๋Œ€์‘์„ ๋ณผ ์ˆ˜ ์žˆ์–ด ์ฝ”๋“œ๊ฐ€ ์ฝ๊ธฐ ์‰ฝ๋‹ค.

2) ์ดˆ๊ธฐ์ž์˜ ๊ฐ’๋“ค์ด ๊ตฌ์กฐ์ฒด์˜ ๊ตฌ์„ฑ์›๊ณผ ๊ฐ™์€ ์ˆœ์„œ์ผ ํ•„์š”๊ฐ€ ์—†๋‹ค.
์ฆ‰, ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•˜์ง€ ์•Š๋‹ค.

์ง€์ • ์ดˆ๊ธฐ์ž์— ์žˆ๋Š” ๋ชจ๋“  ๊ฐ’์ด ๋ฐ˜๋“œ์‹œ ์ง€์ •์ž๋ฅผ ์ ์–ด์ฃผ์–ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

{.number = 528, "Disk drive", .on_hand = 10}



๐Ÿ“ Operations on Structures

๊ตฌ์กฐ์ฒด ๋‚ด์˜ ๊ตฌ์„ฑ์›์— ์ ‘๊ทผํ•˜๋ ค๋ฉด, (๊ตฌ์กฐ์ฒด์˜ ์ด๋ฆ„).(๊ตฌ์„ฑ์›์˜ ์ด๋ฆ„)์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ”Ž part1์˜ ๊ตฌ์„ฑ์› ๊ฐ’๋“ค ์ถœ๋ ฅ

printf("Part number: %d\n", part1.number);
printf("Part name: %s\n", part1.name);
printf("Quantity on hand: %d\n", part1.on_hand);

๊ตฌ์กฐ์ฒด์˜ ๊ตฌ์„ฑ์›์€ lvalue์ด๋‹ค.

๊ตฌ๋‘์ (.)์€ ์—ฐ์‚ฐ์ž๋กœ, ++, -- ๋“ฑ๊ณผ ๊ฐ™์€ ์—ฐ์‚ฐ ์ˆœ์„œ๋ฅผ ๊ฐ€์ง„๋‹ค.

๋˜ํ•œ ๊ตฌ์กฐ์ฒด๋Š” = ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ณต์‚ฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

part2 = part1;

์œ„ ๊ตฌ๋ฌธ์€ part1.number์„ part2.number2์— ๋ณต์‚ฌ, part1.name์€ part2.name์— ๋ณต์‚ฌํ•œ๋‹ค.

๋ฐฐ์—ด์€ = ์—ฐ์‚ฐ์ž๋กœ ๋ณต์‚ฌ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๊ตฌ์กฐ์ฒด ์•ˆ์— ์กด์žฌํ•˜๋Š” ๋ฐฐ์—ด์€ ํ•ด๋‹น ๊ตฌ์กฐ์ฒด๊ฐ€ ๋ณต์‚ฌ๋  ๋•Œ ๊ฐ™์ด ๋ณต์‚ฌ๋œ๋‹ค.

๐Ÿ”Ž ๊ตฌ์กฐ์ฒด ๋‚ด ๋ฐฐ์—ด ๋ณต์‚ฌ

struct { int a[10]; } a1, a2;

a1 = a2; 

= ์—ฐ์‚ฐ์ž๋Š” ํ˜ธํ™˜ ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ์ฒด ๊ฐ„์—๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋™์‹œ์— ์„ ์–ธ๋œ ๋‘ ๊ตฌ์กฐ์ฒด๋‚˜, ๊ฐ™์€ ๊ตฌ์กฐ์ฒด ํƒœ๊ทธ๋ฅผ ๊ฐ–๊ณ  ์„ ์–ธ๋œ ๊ตฌ์กฐ์ฒด, ๊ฐ™์€ ํ˜•๋ช…์„ ๊ฐ–๋Š” ๊ตฌ์กฐ์ฒด๋“ค์ด ์„œ๋กœ ํ˜ธํ™˜๋  ์ˆ˜ ์žˆ๋‹ค.

ํ• ๋‹น ์ด์™ธ์—๋Š” ์ถ”๊ฐ€์ ์ธ ์—ฐ์‚ฐ์ด ์ œ๊ณต๋˜์ง€ ์•Š๋Š”๋‹ค.




๐Ÿ“ Structure Types

๋ณ€์ˆ˜๋ฅผ ํ•œ ๋ฒˆ๋งŒ ์„ ์–ธํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๊ดœ์ฐฎ์ง€๋งŒ, ๋‹ค๋ฅธ ๊ณณ์—์„œ ๋˜ ์„ ์–ธํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ๋ณต์žกํ•ด์ง„๋‹ค.

๐Ÿ”Ž ์—ฌ๋Ÿฌ ๋ฒˆ ์„ ์–ธ

struct {
	int number;
	char name[NAME_LEN + 1];
	int on_hand;
} part1;

struct {
	int number;
	char name[NAME_LEN + 1];
	int on_hand;
} part2;

์ด๋ ‡๊ฒŒ ํ–ˆ์„ ๋•Œ์˜ ๋ฌธ์ œ์ ์€ part1๊ณผ part2๊ฐ€ ํ˜ธํ™˜์ด ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์ด๋‹ค. part1์€ part2์— ํ• ๋‹น๋  ์ˆ˜ ์—†๊ณ , part2๋Š” part1์— ํ• ๋‹น๋  ์ˆ˜ ์—†๋‹ค. ๋˜ํ•œ part1, part2์˜ ํ˜• ์ด๋ฆ„์ด ๋ฌด์—‡์ธ์ง€ ์•Œ ์ˆ˜ ์—†์–ด ํ•จ์ˆ˜ ํ˜ธ์ถœ์—์„œ ์ธ์ˆ˜๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

์ด๋Ÿฐ ์–ด๋ ค์›€๋“ค์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ๊ตฌ์กฐ์ฒด์˜ ์ด๋ฆ„์„ ์ •์˜ํ•œ๋‹ค.

๐Ÿ”Ž structure์˜ ์ด๋ฆ„ ์ง“๊ธฐ

1) ๊ตฌ์กฐ์ฒด ํƒœ๊ทธ(structure tag)๋ฅผ ์„ ์–ธํ•˜๊ธฐ
2) typedef๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ˜• ์ด๋ฆ„ ์ •์˜ํ•˜๊ธฐ


๐Ÿ“ Declaring a Structure Tag

๊ตฌ์กฐ์ฒด ํƒœ๊ทธ(structure tag) : structure์˜ ์ข…๋ฅ˜๋ฅผ ์‹๋ณ„ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์ด๋ฆ„

๐Ÿ”Ž ๊ตฌ์กฐ์ฒด ํƒœ๊ทธ(part) ์„ ์–ธํ•˜๊ธฐ

struct part {
	int number;
	char name[NAME_LEN + 1];
	int on_hand;
};

์ด์ œ part๋ฅผ ๋ณ€์ˆ˜ ์„ ์–ธ์— ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

struct part part1, part2;

์ด ๋•Œ struct๋ฅผ ๋นผ๋จน์œผ๋ฉด ์•ˆ ๋œ๋‹ค. part๋Š” ํ˜• ์ด๋ฆ„์€ ์•„๋‹ˆ๋‹ค.

structure tag๋ฅผ ์„ ์–ธํ•จ๊ณผ ๋™์‹œ์— ๋ณ€์ˆ˜ ์„ ์–ธ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

struct part {
	int number;
	char name[NAME_LEN + 1];
	int on_hand;
} part1, part2;



๐Ÿ“ Defining a Structure Type

typedef๋ฅผ ์ด์šฉํ•˜์—ฌ ์‹ค์ œ ํ˜• ์ด๋ฆ„(type name)์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ”Ž typedef๋ฅผ ์ด์šฉํ•˜์—ฌ ํ˜• ์ด๋ฆ„์„ Part๋กœ ์„ ์–ธํ•˜๊ธฐ

typedef struct {
	int number;
	char name[NAME_LEN + 1];
	int on_hand;
} Part;

Part๋Š” ํ˜• ์ด๋ฆ„์ด๋ฏ€๋กœ structure tag์—์„œ์™€๋Š” ๋‹ค๋ฅด๊ฒŒ Part๋งŒ์„ ์ด์šฉํ•˜์—ฌ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

Part part1, part2;

๐Ÿ”Ž Structure tag vs Typedef

๊ตฌ์กฐ์ฒด๊ฐ€ linked list๋กœ ์‚ฌ์šฉ๋  ๋•Œ๋Š” Structure tag๊ฐ€ ํ•„์ˆ˜์ ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ด ์ฑ…์˜ ๋Œ€๋ถ€๋ถ„์˜ ์˜ˆ์—์„œ๋Š” typedef ๋Œ€์‹  structure tag๋ฅผ ์‚ฌ์šฉํ•˜์˜€๋‹ค.




๐Ÿ“ Structures as Arguments and Return Values

ํ•จ์ˆ˜๋Š” ์ธ์ž(argument)์™€ ๋ฐ˜ํ™˜ ๊ฐ’(return value)๋กœ ๊ตฌ์กฐ์ฒด๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ”Ž ๊ตฌ์กฐ์ฒด๊ฐ€ ์ธ์ž

void print_part(struct part p)
{
	printf("Part number : %d\n", p.number);
	printf("Part name : %s\n", p.name);
	printf("Quantity on hand : %d\n", p.on_hand);
}


print_part(part1); 

๐Ÿ”Ž ๊ตฌ์กฐ์ฒด๊ฐ€ ๋ฐ˜ํ™˜๊ฐ’

struct part build_part(int number, const char* name, int on_hand)
{
	struct part p;

	p.number = number;
	strcpy(p.name, name);
	p.on_hand = on_hand;
	return p;
}

์ด ๋•Œ ๊ตฌ์กฐ์ฒด๋ฅผ ํ•จ์ˆ˜์— ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ๊ณผ, ๊ตฌ์กฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ ๋ชจ๋‘ ๊ตฌ์กฐ์ฒด ๋‚ด ๋ชจ๋“  ๊ตฌ์„ฑ์›์˜ ๋ณต์‚ฌ๊ฐ€ ์ผ์–ด๋‚œ๋‹ค.

๋”ฐ๋ผ์„œ ๊ตฌ์กฐ์ฒด ์ž์ฒด๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ๋ณด๋‹ค ํฌ์ธํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋  ๋•Œ๊ฐ€ ์žˆ๋‹ค. ๋ฐ˜ํ™˜ ๊ฐ’์—์„œ๋„ ํฌ์ธํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋˜ํ•œ ์—ด๋ฆฐ ํŒŒ์ผ์˜ ์ƒํƒœ์—์„œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ ํฌ์ธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํšจ๊ณผ์ ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด <stdio.h>๋Š” FILE์ด๋ผ๋Š” ํ˜•์‹์˜ type ์ด๋ฆ„์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ, ๊ฐ FILE ๊ตฌ์กฐ๋Š” ์—ด๋ฆฐ ํŒŒ์ผ์˜ ์ƒํƒœ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋ฏ€๋กœ ํ”„๋กœ๊ทธ๋žจ์—์„œ ๊ณ ์œ ํ•ด์•ผ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์ด ๊ฒฝ์šฐ๋„ ํฌ์ธํ„ฐ๋ฅผ ์ด์šฉํ•œ๋‹ค.

๊ฒฝ์šฐ์— ๋”ฐ๋ผ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ ๊ตฌ์กฐ์ฒด๋ฅผ ๋‹ค๋ฅธ ๊ตฌ์กฐ์ฒด๋กœ ์ดˆ๊ธฐํ™”์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ”Ž part2๋ฅผ part1์™€ ๋™์ผํ•œ ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”

void f(struct part part1)
{
	struct part part2 = part1;
	...
}



๐Ÿ“ [C99] Compound Literals (๋ณตํ•ฉ๋ฆฌํ„ฐ๋Ÿด)

๊ตฌ์กฐ์ฒด์—์„œ ๋ณตํ•ฉ ๋ฆฌํ„ฐ๋Ÿด์€ ๋จผ์ € ๋ณ€์ˆ˜๋ฅผ ์ €์žฅํ•˜์ง€ ์•Š๊ณ  "์ฆ‰์‹œ" ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ ๊ฒฐ๊ณผ๋ฌผ(๊ตฌ์กฐ์ฒด)๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ๋  ์ˆ˜ ์žˆ๊ณ , ํ•จ์ˆ˜์— ์˜ํ•ด ๋ฐ˜ํ™˜๋  ์ˆ˜ ์žˆ๊ณ , ๋ณ€์ˆ˜์— ํ• ๋‹น๋  ์ˆ˜ ์žˆ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ๋ณตํ•ฉ๋ฆฌํ„ฐ๋Ÿด์€ ๊ด„ํ˜ธ ์•ˆ์˜ ํ˜•์‹ ์ด๋ฆ„๊ณผ, ์ค‘๊ด„ํ˜ธ๋กœ ๋‘˜๋Ÿฌ์‹ธ์ธ ๊ฐ’์˜ ์ง‘ํ•ฉ์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.

๐Ÿ”Ž ๋ณตํ•ฉ๋ฆฌํ„ฐ๋Ÿด์„ ์ด์šฉํ•˜์—ฌ ํ•จ์ˆ˜์— ์ „๋‹ฌ

print_part((struct part) {528, "Disk drive", 10});

๋ณตํ•ฉ๋ฆฌํ„ฐ๋Ÿด์€ part๋ผ๋Š” ๊ตฌ์กฐ์ฒด๋ฅผ ๋งŒ๋“ ๋‹ค.

๐Ÿ”Ž ๋ณตํ•ฉ๋ฆฌํ„ฐ๋Ÿด์„ ์ด์šฉํ•˜์—ฌ ๋ณ€์ˆ˜์— ํ• ๋‹น

part1 = (struct part) {528, "Disk drive", 10};

๋ณตํ•ฉ๋ฆฌํ„ฐ๋Ÿด์€ ์ง€์ •์ž(designators)๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ”Ž ์ง€์ •์ž๊ฐ€ ํฌํ•จ๋œ ๋ณตํ•ฉ ๋ฆฌํ„ฐ๋Ÿด

print_part((struct part) {
		.on_hand = 10,
		.name = "Disk drive",
		.number = 528
});



๐Ÿ“ Nested Arrays and Structures

๊ตฌ์กฐ์ฒด๋Š” ์–ด๋ ˆ์ด์˜ ๊ตฌ์„ฑ์š”์†Œ๋กœ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๊ณ  ์–ด๋ ˆ์ด๋Š” ๊ตฌ์กฐ์ฒด์˜ ๊ตฌ์„ฑ์š”์†Œ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค.




๐Ÿ“ Nested Structures

์•„๋ž˜์™€ ๊ฐ™์€ ๊ตฌ์กฐ์ฒด๊ฐ€ ์žˆ์„ ๋•Œ,

struct person_name {
	char first[FIRST_NAME_LEN + 1];
	char middle_initial;
	char last[LAST_NAME_LEN + 1];
};

๊ตฌ์กฐ์ฒด ์•ˆ์— ๊ตฌ์กฐ์ฒด๋ฅผ ๋„ฃ์„ ์ˆ˜ ์žˆ๋‹ค.

struct student {
	struct person_name name;
	int id, age;
	char sex;
} student1, student2;

์ด ๋•Œ student1์˜ name ์ค‘์—์„œ๋„ first์— ์ ‘๊ทผํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌ๋‘์ (.)์„ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค

strcpy(student1.name.first, "Fred"); 

๐Ÿ”Ž name์„ ๊ตฌ์กฐ์ฒด๋กœ ๋งŒ๋“  ๊ฒƒ์˜ ์žฅ์ 

name์„ ๋ฐ์ดํ„ฐ์˜ ๋‹จ์œ„๋กœ์จ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค. name์„ ์ถœ๋ ฅํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ ์ž ํ•  ๋•Œ, ์ธ์ˆ˜๋กœ ํ•˜๋‚˜๋งŒ ์ „๋‹ฌํ•˜๋ฉด ๋œ๋‹ค.

๐Ÿ”Ž name์„ ์ถœ๋ ฅํ•˜๋Š” ํ•จ์ˆ˜

display_name(student1.name);

๐Ÿ”Ž person_name ๊ตฌ์กฐ์ฒด์—์„œ name์„ student ๊ตฌ์กฐ์ฒด์˜ member๋กœ ๋ณต์‚ฌํ•˜๊ธฐ

struct person_name new_name;
...
student1.name = new_name;



๐Ÿ“ Arrays of Structures

์–ด๋ ˆ์ด์™€ ๊ตฌ์กฐ์ฒด์˜ ๊ฒฐํ•ฉ์—์„œ ์ž์ฃผ ์“ฐ์ด๋Š” ๊ฒƒ ์ค‘ ํ•˜๋‚˜๋Š” ๊ตฌ์กฐ์ฒด๊ฐ€ ์–ด๋ ˆ์ด๋ฅผ ์ด๋ฃจ๋Š” ๊ฒƒ์ด๋‹ค.

์•„๋ž˜ ์˜ˆ์‹œ ๊ตฌ์กฐ์ฒด part์˜ ์–ด๋ ˆ์ด๋Š” part 100๊ฐœ์˜ ์ •๋ณด๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค

struct part inventory[100];

์ด ์–ด๋ ˆ์ด์˜ ์š”์†Œ์— ์ ‘๊ทผํ•˜๋ ค๋ฉด ๋ฐฐ์—ด์ฒจ์ž[ ]๋ฅผ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค.

print_part(inventory[i]);

๊ตฌ์กฐ์ฒด part์˜ ๊ตฌ์„ฑ์›(member)์— ์ ‘๊ทผํ•˜๋ ค๋ฉด ๋ฐฐ์—ด์ฒจ์ž์™€ ๊ตฌ๋‘์ ์„ ์ด์šฉํ•˜์—ฌ ๋ฉค๋ฒ„๋ฅผ ์„ ํƒํ•˜๋ฉด ๋œ๋‹ค.

๐Ÿ”Ž inventory[i]์˜ ๊ตฌ์„ฑ์› number์— 883 ํ• ๋‹นํ•˜๊ธฐ

inventory[i].number = 883;

name์˜ ๋ฌธ์ž ํ•˜๋‚˜์— ์ ‘๊ทผํ•˜๋ ค๋ฉด ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ฐฐ์—ด ์ฒจ์ž๋ฅผ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค.

๐Ÿ”Ž inventory[i]์— ์ €์žฅ๋œ name์„ ๋นˆ ๋ฌธ์ž์—ด๋กœ ๋งŒ๋“ค๊ธฐ

inventory[i].name[0] = '\0';



๐Ÿ“ Initializing an Array of Structures

๊ตฌ์กฐ์ฒด ์–ด๋ ˆ์ด๋ฅผ ์ดˆ๊ธฐํ™” ํ•˜๋Š” ๊ฒƒ์€ ๋‹ค์ฐจ์› ์–ด๋ ˆ์ด๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฑฐ์˜ ๋™์ผํ•˜๋‹ค.
๊ตฌ์กฐ์ฒด ์–ด๋ ˆ์ด๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ์ด์œ  ์ค‘ ํ•˜๋‚˜๋Š” ์ด๋ฅผ ์‹คํ–‰ ์ค‘ ๊ฐ’์ด ๋ณ€ํ•˜์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ทจ๊ธ‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ด๋‹ค.

๐Ÿ”Ž ๊ตฌ์กฐ์ฒด๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ตญ๊ฐ€๋ฒˆํ˜ธ ์ €์žฅํ•˜๊ธฐ

struct dialing_code {
	char* country;
	int code;
};

๐Ÿ”Ž ์œ„ ๊ตฌ์กฐ์ฒด๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ์–ด๋ ˆ์ด ์ดˆ๊ธฐํ™” ํ•˜๊ธฐ

const struct dialing_code country_codes[] = {
	{"Argentina",		54}, {"Bangladesh",		880},
	{"Brazil",		55}, {"Burma (Myanmar)",	 95}
    ...
};
struct part inventory[100] =
{ [0] .number = 528, [0].on_hand = 10, [0].name[0] = '\0' };



๐Ÿ“ [PROGRAM] Maintaining a Parts Database

์ฐฝ๊ณ ์— ๋‚จ์•„์žˆ๋Š” ๋ถ€ํ’ˆ๋“ค์„ ํ‘œ์‹œํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•ด๋ณด์ž
๋“ค์–ด๊ฐˆ ์ •๋ณด๋Š” ๋ถ€ํ’ˆ ๋ฒˆํ˜ธ, ์ด๋ฆ„, ์ˆ˜๋Ÿ‰์ด๋‹ค.

  • ์ƒˆ๋กœ์šด ๋ถ€ํ’ˆ ๋ฒˆํ˜ธ, ์ด๋ฆ„, ๋‚จ์€ ์ˆ˜๋Ÿ‰์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. ๋งŒ์•ฝ ์ด๋ฏธ ํ•ด๋‹น ๋ถ€ํ’ˆ์ด ์žˆ๊ฑฐ๋‚˜ ๊ฐ€๋“์ฐฌ ๊ฒฝ์šฐ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

  • ๋ถ€ํ’ˆ ๋ฒˆํ˜ธ๊ฐ€ ์ฃผ์–ด์ง€๋ฉด ์ด๋ฆ„, ๋‚จ์€ ์ˆ˜๋Ÿ‰์„ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. ๋งŒ์•ฝ ํ•ด๋‹น ๋ถ€ํ’ˆ์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์—†๋‹ค๋ฉด ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

  • ๋ถ€ํ’ˆ ๋ฒˆํ˜ธ๊ฐ€ ์ฃผ์–ด์ง€๋ฉด ๋‚จ์€ ์ˆ˜๋Ÿ‰์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. ๋งŒ์•ฝ ํ•ด๋‹น ๋ถ€ํ’ˆ์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์—†๋‹ค๋ฉด ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋‹ด๊ธด ์ •๋ณด ์ „์ฒด๋ฅผ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. ์ž…๋ ฅํ•œ ์ˆœ์„œ๋Œ€๋กœ ์ถœ๋ ฅ๋˜๋„๋ก ํ•œ๋‹ค.

  • ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ์ข…๋ฃŒ

์ด ํ–‰๋™๋“ค์„ ํ•˜๊ธฐ ์œ„ํ•ด i(insert), s(search), u(update), p(print), q(quit)์„ ์ด์šฉํ•œ๋‹ค.

๐Ÿ”Ž inventory.c

#include <stdio.h>
#include "readline.h"

#define NAME_LEN 25
#define MAX_PARTS 100

struct part {
	int number;
	char name[NAME_LEN + 1];
	int on_hand;
} inventory[MAX_PARTS];

int num_parts = 0;

int find_part(int number);
void insert(void);
void search(void);
void update(void);
void print(void);

int main(void)
{
	char code;
	for (;;) {
		printf("Enter operation code : ");
		scanf(" %c", &code);
		while (getchar() != '\n');
		switch (code) {
		case 'i': insert();
			break;
		case 's': search();
			break;
		case 'u': update();
			break;
		case 'p': print();
			break;
		case 'q': return 0;
		default: printf("Illegal code\n");
		}
		printf("\n");
	}
}

int find_part(int number)
{
	int i;

	for (i = 0; i < num_parts; i++)
		if (inventory[i].number == number)
			return i;
	return -1;
}

void insert(void)
{
	int part_number;

	if (num_parts == MAX_PARTS) {
		printf("Database is full; can't add more parts.\n");
		return;
	}

	printf("Enter part number : ");
	scanf("%d", &part_number);

	if (find_part(part_number) >= 0) {
		printf("Part already exists.\n");
		return;
	}

	inventory[num_parts].number = part_number;
	printf("Enter part name : ");
	read_line(inventory[num_parts].name, NAME_LEN);
	printf("Enter quantity on hand : ");
	scanf("%d", &inventory[num_parts].on_hand);
	num_parts++;
}

void search(void)
{
	int i, number;

	printf("Enter part number : ");
	scanf("%d", &number);
	i = find_part(number);
	if (i >= 0) {
		printf("Part name : %s\n", inventory[i].name);
		printf("Quantity on hand : %d\n", inventory[i].on_hand);
	}
	else
		printf("Part not found.\n");
}

void update(void)
{
	int i, number, change;

	printf("Enter part number : ");
	scanf("%d", &number);
	i = find_part(number);
	if (i >= 0) {
		printf("Enter change in quantity on hand : ");
		scanf("%d", &change);
		inventory[i].on_hand += change;
	}
	else
		printf("Part not found.\n");
}

void print(void)
{
	int i;

	printf("Part Number		Part Name			"
		"Quantity on Hand\n");
	for (i = 0; i < num_parts; i++)
		printf("%7d			%-25s%11d\n", inventory[i].number,
			inventory[i].name, inventory[i].on_hand);
}

๐Ÿ”Ž readline.h

#ifndef READLINE_H
#define READLINE_H

int read_line(char str[], int n);

#endif

๐Ÿ”Ž readline.c

  
#include <ctype.h>
#include <stdio.h>
#include "readline.h"

int read_line(char str[], int n)
{
	int ch, i = 0;

	while (isspace(ch = getchar()));
	while (ch != '\n' && ch != EOF) {
		if (i < n)
			str[i++] = ch;
		ch = getchar();
	}
	str[i] = '\0';
	return i;
}
                  



๐Ÿ“ Unions

๊ณต์šฉ์ฒด(union)๋Š” ๊ตฌ์กฐ์ฒด ์ฒ˜๋Ÿผ ํ•˜๋‚˜ ์ด์ƒ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ์œ ํ˜•์˜ ๊ตฌ์„ฑ์›(member)์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๊ฐ€์žฅ ํฐ ๊ตฌ์„ฑ์›์„ ์œ„ํ•œ ๊ณต๊ฐ„๋งŒ์„ ํ• ๋‹นํ•˜๊ณ , ์„œ๋กœ ์ด ๊ณต๊ฐ„์„ ๊ณต์œ ํ•œ๋‹ค.

๐Ÿ”Ž ๊ณต์šฉ์ฒด ์„ ์–ธ

union {
	int i;
	double d;
} u;

๐Ÿ”Ž ๊ณต์šฉ์ฒด vs ๊ตฌ์กฐ์ฒด

struct {
	int i;
	double d;
} u;

๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•  ๋•Œ ๋‘˜์˜ ์ฐจ์ด๋Š” ๋ฉ”๋ชจ๋ฆฌ์˜ ์ฃผ์†Œ์— ์žˆ๋‹ค.

๐Ÿ”Ž ๊ณต์šฉ์ฒด ์„ ์–ธ - u์˜ ๊ตฌ์„ฑ์› i์— 82 ํ• ๋‹นํ•˜๊ธฐ

u.i = 82;

๊ณต์šฉ์ฒด์˜ ๊ฒฝ์šฐ ํ•œ ๋ฉค๋ฒ„๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ๋‹ค๋ฅธ ๋ฉค๋ฒ„์— ์ €์žฅ๋˜์–ด ์žˆ๋˜ ๊ฐ’๋“ค์ด ๋ณ€ํ™”ํ•œ๋‹ค.
๋”ฐ๋ผ์„œ ์ด ๊ฒฝ์šฐ u.d์˜ ๊ฐ’์„ ๋ณ€ํ™”์‹œ์ผœ์ฃผ๋ฉด u.i์— ์ €์žฅ๋œ ๊ฐ’์€ ์‚ฌ๋ผ์ง„๋‹ค.

๋”ฐ๋ผ์„œ ๊ณต์šฉ์ฒด u๋Š” i, d ๋‘˜๋‹ค๊ฐ€ ์•„๋‹Œ i๋‚˜ d ์ค‘ ํ•˜๋‚˜๋ฅผ ์ €์žฅ์‹œํ‚ค๋Š” ๊ณต๊ฐ„์ด๋‹ค.

๊ณต์šฉ์ฒด์˜ ํŠน์„ฑ์€ ๊ตฌ์กฐ์ฒด์™€ ๊ฑฐ์˜ ๋™์ผํ•˜๋‹ค. tag์™€ type์„ ๋™์ผํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ = ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•˜์—ฌ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค๋งŒ ๊ณต์šฉ์ฒด์—์„œ๋Š” ์ฒซ๋ฒˆ์งธ ๊ตฌ์„ฑ์›๋งŒ ์ดˆ๊ธฐํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

union {
	int i;
	double d;
} u = { 0 };

C99์—์„œ๋Š” ์–ด๋–ค ๊ตฌ์„ฑ์›์„ ์ดˆ๊ธฐํ™”ํ• ์ง€ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ตฌ์„ฑ์› ํ•˜๋‚˜๋งŒ ์ดˆ๊ธฐํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‚˜, ๊ผญ ์ฒซ๋ฒˆ์งธ์ผ ํ•„์š”๋Š” ์—†๋‹ค.

union {
	int i;
	double d;
} u = { .d = 10.0 };



๐Ÿ“ Using Unions to Save Space

์•„๋ž˜์˜ ์„ ๋ฌผ ๋ชฉ๋ก์„ ์ €์žฅํ•˜๊ณ ์ž ํ•  ๋•Œ,

Books : Title, author, number of pages
Mugs : Design
Shirts : Design, colors avialable, sizes available

๊ตฌ์กฐ์ฒด๋ฅผ ๋งŒ๋“ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

struct catalog_item {
	int stock_number;
	double price;
	int item_type;
	char title[TITLE_LEN + 1];
	char author[AUTHOR_LEN + 1];
	int num_pages;
	char design[DESIGN_LEN + 1];
	int colors;
	int sizes;
};

BOOK, MUG, SHIRT ๋ชจ๋‘ item_type์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋งŒ, colors, size ๋“ฑ์€ shirts๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ณต๊ฐ„ ๋‚ญ๋น„๊ฐ€ ์ผ์–ด๋‚˜๊ฒŒ ๋œ๋‹ค. ์ฆ‰ ์ฑ…์˜ ๊ฒฝ์šฐ design, colors, sizes๋ฅผ ์ €์žฅํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

์ด ๊ฒฝ์šฐ ๊ตฌ์กฐ์ฒด์— ๊ณต์šฉ์ฒด๋ฅผ ๋„ฃ์œผ๋ฉด ๊ณต๊ฐ„๋‚ญ๋น„๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค. ๊ณต์šฉ์ฒด์˜ ๊ตฌ์„ฑ์›์€ ๊ฐ๊ฐ์˜ ํŠน์ˆ˜ํ•œ ๋ชฉ๋ก์„ ๋‹ด์€ ๊ตฌ์กฐ์ฒด์ด์–ด์•ผ ํ•œ๋‹ค. ์ฆ‰ ๊ฒน์น˜์ง€ ์•Š๋Š” ๊ฒƒ๋“ค์€ ๊ตฌ์กฐ์ฒด ๋‚ด ๊ณต์šฉ์ฒด์— ๋‹ด์œผ๋ฉด ๋œ๋‹ค.

๐Ÿ”Ž ๊ณต์šฉ์ฒด๋ฅผ ์ด์šฉํ•œ catalog_item

struct catalog_item {
	int stock_number;
	double price;
	int item_type;
	union {
		struct {
			char title[TITLE_LEN + 1];
			char author[AUTHOR_LEN + 1];
			int num_pages
		} book;
		struct {
			char design[DESIGN_LEN + 1];
		} mug;
		struct {
			char design[DESIGN_LEN + 1];
			int colors;
			int sizes;
		} shirt;
	} item;
};

๋งŒ์•ฝ c๊ฐ€ ์ฑ…์„ ๊ฐ€๋ฆฌํ‚ค๋Š” catalog_item ๊ตฌ์กฐ์ฒด๋ผ๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฑ…์˜ title์„ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ๋‹ค.

printf("%s", c.item.book.title);

๋งŒ์•ฝ mug์˜ design์— "Cats"๋ฅผ ํ• ๋‹นํ•œ๋‹ค๋ฉด, ๊ณต์šฉ์ฒด ๋‚ด ๋‹ค๋ฅธ ๊ตฌ์กฐ์ฒด์˜ design์—๋„ ๋˜‘๊ฐ™์ด "Cats"๊ฐ€ ํ• ๋‹น๋œ๋‹ค.

strcpy(c.item.mug.design, "Cats");

printf("%s", c.item.shirt.design); /* prints "Cats" */



๐Ÿ“ Using Unions to Build Mixed Data Structures

union์„ ํ™œ์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ์œ ํ˜•์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ํ˜ผํ•ฉ๋œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

๋งŒ์•ฝ int์™€ double์ด ํ˜ผํ•ฉ๋œ ์–ด๋ ˆ์ด๋ฅผ ๋งŒ๋“ ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž. ์–ด๋ ˆ์ด๋Š” ํ•œ ๊ฐ€์ง€์˜ ์œ ํ˜•๋งŒ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ๊ณต์šฉ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ€๋Šฅํ•˜๋‹ค.

๋จผ์ € ์„œ๋กœ ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๋Š” ๊ณต์šฉ์ฒด๋ฅผ ๋งŒ๋“ ๋‹ค.

typedef union {
	int i;
	double d;
} Number;

๊ทธ ํ›„, ์š”์†Œ๊ฐ€ Number์ธ ์–ด๋ ˆ์ด๋ฅผ ์ œ์ž‘ํ•˜๋ฉด ๋œ๋‹ค.

Number number_array[1000];

๊ทธ๋Ÿผ number_array์—๋Š” int ์™€ double ๋ชจ๋‘๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.

number_array[0].i = 5;
number_array[1].d = 8.395;



๐Ÿ“ Adding a "Tag Field" to a Union

Union์—๋Š” ์น˜๋ช…์ ์ธ ๋‹จ์ ์ด ์žˆ๋‹ค. ์ตœ๊ทผ์— ์–ด๋–ค ๊ตฌ์„ฑ์›์ด ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์—†์–ด ์˜๋ฏธ์—†๋Š” ๊ฐ’์ด ๋‹ด๊ฒจ์žˆ์–ด๋„ ์•Œ ์ˆ˜๊ฐ€ ์—†๋‹ค.

์šฐ๋ฆฌ๋Š” ์กฐํ•ฉ์— ํ˜„์žฌ ์ €์žฅ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์„ ์ƒ๊ธฐ์‹œํ‚ค๋Š” ๊ฒƒ์„ ๋ชฉ์ ์œผ๋กœ ํƒœ๊ทธ ํ•„๋“œ(tag field) ๋˜๋Š” ์ฐจ๋ณ„์ž(discriminant)๋ฅผ ๊ตฌ์กฐ์ฒด ์•ˆ์— ๊ณต์šฉ์ฒด๋ฅผ ํฌํ•จ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

์•ž์„œ catalog_item ๊ตฌ์กฐ์ฒด์—์„œ๋Š” item_type์ด ์ด๋Ÿฌํ•œ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

๐Ÿ”Ž tag field๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ตฌ์กฐ์ฒด ์„ ์–ธ

#define INT_KIND 0
#define DOUBLE_KIND 1

typedef struct {
	int kind; /* tag field */
	union {
		int i;
		double d;
	} u;
} Number; 

kind๋Š” INT_KIND๊ฑฐ๋‚˜ DOUBLE_KIND์ด๋‹ค.

u์˜ ๊ตฌ์„ฑ์›์— ๊ฐ’์„ ํ• ๋‹นํ•  ๋•Œ ๋งˆ๋‹ค ์ˆ˜์ •์‚ฌํ•ญ์„ ์ƒ๊ธฐํ‚ค์‹œ๊ธฐ ์œ„ํ•ด kind๋„ ํ•จ๊ป˜ ๋ณ€๊ฒฝ์‹œํ‚ค๋ฉด ๋œ๋‹ค.

๐Ÿ”Ž n์ด Number์˜ ๋ณ€์ˆ˜์ธ ๊ฒฝ์šฐ u์˜ i ๋ฉค๋ฒ„๋ฅผ ํ• ๋‹นํ•˜๊ธฐ

n.kind = INT_KIND;
n.u.i = 82;

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด Number ๋ณ€์ˆ˜์— ์ง€์ •๋œ ์ˆซ์ž๋ฅผ ๊ฒ€์ƒ‰ํ•ด์•ผ ํ•  ๋•Œ, kind๋Š” ์–ด๋–ค ๊ณต์šฉ์ฒด๊ฐ€ ๋งˆ์ง€๋ง‰์œผ๋กœ ๊ฐ’์„ ํ• ๋‹น๋ฐ›์•˜๋Š”์ง€ ์•Œ๋ ค์ค€๋‹ค.

void print_number(Number n)
{
if (n.kind == INT_KIND)
printf("%d", n.u.i);
else
printf("%g", n.u.d);
}




๐Ÿ“ Enumerations

๋งŽ์€ ํ”„๋กœ๊ทธ๋žจ์—์„œ, ๋‹จ์ง€ ์ž‘์€ ์˜๋ฏธ ์žˆ๋Š” ๊ฐ’๋“ค์˜ ์ง‘ํ•ฉ๋งŒ์„ ๊ฐ€์ง„ ๋ณ€์ˆ˜๋“ค์ด ํ•„์š”ํ•  ๊ฒƒ์ด๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ์นด๋“œ ๊ฒŒ์ž„์—์„œ ์นด๋“œ๋ช…์„ ์ €์žฅํ•˜๋Š” ๋ณ€์ˆ˜๋Š” "ํด๋กœ๋ฒ„" "๋‹ค์ด์•„๋ชฌ๋“œ" "ํ•˜ํŠธ" "์ŠคํŽ˜์ด๋“œ" 4๊ฐ€์ง€์˜ ๊ฐ’์ด ํ•„์š”ํ•˜๋‹ค.

์ด๋Ÿฌํ•œ ๋ณ€์ˆ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํ™•์‹คํ•œ ๋ฐฉ๋ฒ•์€ ๊ฐ€๋Šฅํ•œ ๋ณ€์ˆ˜์˜ ๊ฐ’๊ณผ ์ •์ˆ˜๋ฅผ ๋งค์น˜์‹œํ‚ค๋Š” ๊ฒƒ์ด๋‹ค.

int s; /* s will store a suit */
...
s = 2; /* 2 represents "hearts" */

์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ ์ด 4๊ฐ€์ง€์˜ ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋Š” ์ ์ด๋‚˜, 2๊ฐ€ ์˜๋ฏธํ•˜๋Š” ๋ฐ” ๋“ฑ์ด ์ง๊ด€์ ์ด์ง€ ์•Š๋‹ค.

๋งคํฌ๋กœ๋ฅผ ์ด์šฉํ•˜์—ฌ suit์˜ ์œ ํ˜•๊ณผ ์ด๋ฆ„์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

#define SUIT int 
#define CLUBS 0
#define DIAMONDS 0
#define HEARTS 0
#define SPADES 0

์ด ๊ฒฝ์šฐ ์ข€ ๋” ์ฝ๊ธฐ ์‰ฝ๋„๋ก ๋งŒ๋“ค์–ด์ง„๋‹ค

SUIT s;
...
s = HEARTS;

๊ทธ๋Ÿฌ๋‚˜ ์™„๋ฒฝํ•œ ํ•ด๊ฒฐ์ฑ…์€ ์•„๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋žจ์„ ์ฝ๋Š” ์‚ฌ๋žŒ์—๊ฒŒ๋Š” ๋งคํฌ๋กœ๊ฐ€ ๋™์ผํ•œ "์œ ํ˜•"์˜ ๊ฐ’์„ ๋‚˜ํƒ€๋‚ธ๋‹ค๋Š” ํ‘œ์‹œ๊ฐ€ ์—†๋‹ค. ๋˜ํ•œ ์ •์˜ํ•œ ์ด๋ฆ„์€ ์ „์ฒ˜๋ฆฌ์— ์˜ํ•ด ์ œ๊ฑฐ๋˜๋ฏ€๋กœ ๋””๋ฒ„๊น… ์ค‘์— ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

C๋Š” ๊ฐ€๋Šฅํ•œ ๊ฐ’์˜ ์ˆ˜๊ฐ€ ์ ์€ ๋ณ€์ˆ˜๋ฅผ ์œ„ํ•ด ํŠน๋ณ„ํžˆ ์„ค๊ณ„๋œ ํŠน์ˆ˜ํ•œ ์œ ํ˜•์„ ์ œ๊ณตํ•œ๋‹ค. ์—ด๊ฑฐํ˜•(enumerated type)์€ ํ”„๋กœ๊ทธ๋ž˜๋จธ์— ์˜ํ•ด ๊ฐ’์ด ๋‚˜์—ด๋˜๋Š” ์œ ํ˜•์ด๋ฉฐ, ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ๊ฐ ๊ฐ’์— ๋Œ€ํ•œ ์ด๋ฆ„(enumeration constant)์„ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿ”Ž ๋ณ€์ˆ˜ s1๊ณผ s2์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์„ ์—ด๊ฑฐ

enum {CLUBS, DIAMONDS, HEARTS, SPADES} s1, s2; 

์—ด๊ฑฐํ˜•์ด ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์„ ์–ธ๋˜๋ฉด ํ•ด๋‹น ์ƒ์ˆ˜๋Š” ํ•จ์ˆ˜ ์™ธ๋ถ€์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.


๐Ÿ“ Enumeration Tags and Type Names

๊ตฌ์กฐ์ฒด, ๊ณต์šฉ์ฒด์™€ ํ•จ๊ป˜ ์—ด๊ฑฐํ˜•์˜ ์ด๋ฆ„์„ ์ง€์„ ๋‘๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค. tag๋ฅผ ์„ ์–ธํ•˜๊ฑฐ๋‚˜ typedef๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์ œ ํ˜• ์ด๋ฆ„์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค.

์—ด๊ฑฐํ˜• ํƒœ๊ทธ๋Š” ๊ตฌ์กฐ์ฒด, ๊ณต์šฉ์ฒด ํƒœ๊ทธ์™€ ์œ ์‚ฌํ•˜๋‹ค.

๐Ÿ”Ž suit ํƒœ๊ทธ ์ •์˜

enum suit {CLUBS, DIAMONDS, HEARTS, SPADES};

๐Ÿ”Ž suit์˜ ๋ณ€์ˆ˜ ์ •์˜

enum suit s1, s2;

๋Œ€์•ˆ์œผ๋กœ Suit๋ฅผ ํ˜• ์ด๋ฆ„์œผ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด typedef๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค

typedef enum {CLUBS, DIAMONDS, HEARTS, SPADES} Suit; 
Suit s1, s2;



๐Ÿ“ Enumerations as Integers

C๋Š” ์—ด๊ฑฐํ˜• ๋ณ€์ˆ˜๋“ค์„ ์ •์ˆ˜์ฒ˜๋Ÿผ ๋‹ค๋ฃฌ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๊ฐ๊ฐ์˜ ์—ด๊ฒจํ˜•๋“ค์— 0, 1, 2.. ๋ฅผ ํ• ๋‹นํ•œ๋‹ค. ์•ž์„œ suit ์—ด๊ฑฐํ˜•์„ ์˜ˆ์‹œ๋กœ ๋“ค๋ฉด, CLUBS, DIAMONDS, HEARTS, SPADES๋Š” ๊ฐ๊ฐ 0, 1, 2, 3์— ๋Œ€์‘๋œ๋‹ค.

๋‹ค๋ฅธ ์ƒ์ˆ˜๋ฅผ ๋„ฃ๊ณ  ์‹ถ๋‹ค๋ฉด ์›ํ•˜๋Š” ๊ฐ’์„ ํ• ๋‹นํ•ด์ค„ ์ˆ˜๋„ ์žˆ๋‹ค.

enum suit {CLUBS = 1, DIAMONDS = 2, HEARTS = 3, SPADES = 4};

๊ฐ™์€ ์ƒ์ˆ˜๋ฅผ ๊ฐ–๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.
์—ด๊ฑฐํ˜•์€ ๊ฒฐ๊ตญ ์ •์ˆ˜์ด๋ฏ€๋กœ ๋‹ค๋ฅธ ์ •์ˆ˜์™€ ์„ž๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

int i;
enum {CLUBS, DIAMONDS, HEARTS, SPADES} s;

i = DIAMONDS;
s = 0;
s++;
i = s + 2; 

์ปดํŒŒ์ผ๋Ÿฌ๋Š” s๋ฅผ ์ •์ˆ˜์ฒ˜๋Ÿผ ๋‹ค๋ฃฌ๋‹ค.




๐Ÿ“ Using Enumerations to Declare "Tag Fields"

์•ž์„œ 16.4 ์ ˆ์—์„œ ๋‹ค๋ฃจ์—ˆ๋˜, ์ตœ๊ทผ์— ์ˆ˜์ •๋œ ๊ฐ’๋“ค์„ ํŒŒ์•…ํ•˜๋Š”๋ฐ ์—ด๊ฑฐํ˜•์€ ํšจ๊ณผ์ ์ด๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด kind ๋ณ€์ˆ˜๋ฅผ int ๋Œ€์‹  ์—ด๊ฑฐํ˜•์œผ๋กœ ๋งŒ๋“ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

๐Ÿ”Ž ์—ด๊ฑฐํ˜•์„ ์ด์šฉํ•ด kind ๋งŒ๋“ค๊ธฐ

typedef struct {
	enum {INT_KIND, DOUBLE_KIND} kind;
	union {
		int i;
		double d;
	} u;
} Number;


profile
๊ณต๋ถ€์ •๋ฆฌ์šฉ

0๊ฐœ์˜ ๋Œ“๊ธ€