C Programming, A Modern Approach - K.N.KING์ผ๋ก C์ธ์ด๋ฅผ ๊ณต๋ถํ๋ฉด์ ์ ๋ฆฌํ ๋ด์ฉ์
๋๋ค.
๋ฒ์ญ๋ณธ https://wikidocs.net/book/2494 ์ ์ฐธ๊ณ ํ์์ต๋๋ค.
๊ตฌ์กฐ์ฒด : ์๋ก ๋ค๋ฅธ ํ์ ๊ฐ์ง ์๋ ์๋ ๊ฐ(๊ตฌ์ฑ์)์ ์งํฉ
๊ณต์ฉ์ฒด : ๊ตฌ์กฐ์ฒด์ ์ ์ฌํ๋ ๊ฐ ๊ตฌ์ฑ์์ด ๊ฐ์ ์ ์ฅ ๊ณต๊ฐ์ ๊ณต์ , ๊ทธ๋ ๊ธฐ์ ๊ณต์ฉ์ฒด๋ ํ ๋ฒ์ ๋์์ ๋ชจ๋ ๊ตฌ์ฑ์์ ์ ์ฅํ ์ ์๊ณ , ํ ๊ตฌ์ฑ์๋ง์ ์ ์ฅ
์ด๊ฑฐํ : ํ๋ก๊ทธ๋๋จธ๊ฐ ๋ช
๋ช
ํ ๊ฐ์ผ๋ก ๋ ์ ์ํ
๊ตฌ์กฐ์ฒด์ ์์(member)๋ ๊ฐ์ ํ์ผ ํ์๊ฐ ์๋ค.
๊ตฌ์กฐ์ฒด์ ๊ตฌ์ฑ์๋ค์๊ฒ ์ด๋ฆ์ด ์กด์ฌํ์ฌ ํน์ ๊ตฌ์ฑ์์ ์ ํํ๋ ค๋ฉด ์์น๊ฐ ์๋ ์ด๋ฆ์ ํน์ ํด์ฃผ์ด์ผ ํ๋ค.
๐ ๋ถํ ๋ฒํธ, ๋ถํ ์ด๋ฆ, ๋ถํ ๊ฐ์ ์ ์ฅํ๊ธฐ
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;
๐ ๊ตฌ์กฐ์ฒด ์ ์ธ ์์ ์ด๊ธฐํํ๊ธฐ
struct {
int number;
char name[NAME_LEN + 1];
int on_hand;
} part1 = { 528, "Disk drive", 10 },
part2 = { 914, "Printer cable", 5 };
์ด๊ธฐํํ ๊ตฌ์กฐ์ฒด์ ๊ตฌ์ฑ์ ์๋ณด๋ค ์ ์ ์์ ์ด๊ธฐ์๊ฐ ์ฃผ์ด์ง ๊ฒฝ์ฐ ๋๋จธ์ง ์ด๊น๊ฐ์ 0์ด ๋๋ค. ํนํ ๋ฌธ์ํ ๋ฐฐ์ด์ ๋๋จธ์ง ๋ฐ์ดํธ๋ค์ 0์ด ๋์ด ๋น์ด์๋ ๋ฌธ์์ด์ด ๋๋ค.
๐ ์ง์ ์ด๊ธฐ์
{.number = 528, .name = "Disk drive", .on_hand = 10}
์ง์ ์(designator) : ๊ตฌ๋์ (.) + ๊ตฌ์ฑ์ ์ด๋ฆ
๐ ์ง์ ์ด๊ธฐ์์ ์ฅ์
1) ๊ตฌ์กฐ์ฒด์ ๊ตฌ์ฑ์๊ณผ ์ด๊ธฐ์ ๊ฐ์ ๋์์ ๋ณผ ์ ์์ด ์ฝ๋๊ฐ ์ฝ๊ธฐ ์ฝ๋ค.
2) ์ด๊ธฐ์์ ๊ฐ๋ค์ด ๊ตฌ์กฐ์ฒด์ ๊ตฌ์ฑ์๊ณผ ๊ฐ์ ์์์ผ ํ์๊ฐ ์๋ค.
์ฆ, ์์๊ฐ ์ค์ํ์ง ์๋ค.
์ง์ ์ด๊ธฐ์์ ์๋ ๋ชจ๋ ๊ฐ์ด ๋ฐ๋์ ์ง์ ์๋ฅผ ์ ์ด์ฃผ์ด์ผ ํ๋ ๊ฒ์ ์๋๋ค.
{.number = 528, "Disk drive", .on_hand = 10}
๊ตฌ์กฐ์ฒด ๋ด์ ๊ตฌ์ฑ์์ ์ ๊ทผํ๋ ค๋ฉด, (๊ตฌ์กฐ์ฒด์ ์ด๋ฆ).(๊ตฌ์ฑ์์ ์ด๋ฆ)์ผ๋ก ์ ๊ทผํ ์ ์๋ค.
๐ 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;
= ์ฐ์ฐ์๋ ํธํ ๊ฐ๋ฅํ ๊ตฌ์กฐ์ฒด ๊ฐ์๋ง ์ฌ์ฉํ ์ ์๋ค. ๋์์ ์ ์ธ๋ ๋ ๊ตฌ์กฐ์ฒด๋, ๊ฐ์ ๊ตฌ์กฐ์ฒด ํ๊ทธ๋ฅผ ๊ฐ๊ณ ์ ์ธ๋ ๊ตฌ์กฐ์ฒด, ๊ฐ์ ํ๋ช ์ ๊ฐ๋ ๊ตฌ์กฐ์ฒด๋ค์ด ์๋ก ํธํ๋ ์ ์๋ค.
ํ ๋น ์ด์ธ์๋ ์ถ๊ฐ์ ์ธ ์ฐ์ฐ์ด ์ ๊ณต๋์ง ์๋๋ค.
๋ณ์๋ฅผ ํ ๋ฒ๋ง ์ ์ธํ๋ ๊ฒฝ์ฐ๋ ๊ด์ฐฎ์ง๋ง, ๋ค๋ฅธ ๊ณณ์์ ๋ ์ ์ธํด์ผ ํ๋ ๊ฒฝ์ฐ์๋ ๋ณต์กํด์ง๋ค.
๐ ์ฌ๋ฌ ๋ฒ ์ ์ธ
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๋ฅผ ์ฌ์ฉํ์ฌ ํ ์ด๋ฆ ์ ์ํ๊ธฐ
๊ตฌ์กฐ์ฒด ํ๊ทธ(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;
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๋ฅผ ์ฌ์ฉํ์๋ค.
ํจ์๋ ์ธ์(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;
...
}
๊ตฌ์กฐ์ฒด์์ ๋ณตํฉ ๋ฆฌํฐ๋ด์ ๋จผ์ ๋ณ์๋ฅผ ์ ์ฅํ์ง ์๊ณ "์ฆ์" ๊ตฌ์กฐ๋ฅผ ๋ง๋๋๋ฐ ์ฌ์ฉ๋ ์ ์๋ค. ๊ทธ ๊ฒฐ๊ณผ๋ฌผ(๊ตฌ์กฐ์ฒด)๋ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ๋ ์ ์๊ณ , ํจ์์ ์ํด ๋ฐํ๋ ์ ์๊ณ , ๋ณ์์ ํ ๋น๋ ์ ์๋ค.
์ผ๋ฐ์ ์ผ๋ก ๋ณตํฉ๋ฆฌํฐ๋ด์ ๊ดํธ ์์ ํ์ ์ด๋ฆ๊ณผ, ์ค๊ดํธ๋ก ๋๋ฌ์ธ์ธ ๊ฐ์ ์งํฉ์ผ๋ก ๊ตฌ์ฑ๋๋ค.
๐ ๋ณตํฉ๋ฆฌํฐ๋ด์ ์ด์ฉํ์ฌ ํจ์์ ์ ๋ฌ
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
});
๊ตฌ์กฐ์ฒด๋ ์ด๋ ์ด์ ๊ตฌ์ฑ์์๋ก ๋ค์ด๊ฐ ์ ์๊ณ ์ด๋ ์ด๋ ๊ตฌ์กฐ์ฒด์ ๊ตฌ์ฑ์์๊ฐ ๋ ์ ์๋ค.
์๋์ ๊ฐ์ ๊ตฌ์กฐ์ฒด๊ฐ ์์ ๋,
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;
์ด๋ ์ด์ ๊ตฌ์กฐ์ฒด์ ๊ฒฐํฉ์์ ์์ฃผ ์ฐ์ด๋ ๊ฒ ์ค ํ๋๋ ๊ตฌ์กฐ์ฒด๊ฐ ์ด๋ ์ด๋ฅผ ์ด๋ฃจ๋ ๊ฒ์ด๋ค.
์๋ ์์ ๊ตฌ์กฐ์ฒด 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';
๊ตฌ์กฐ์ฒด ์ด๋ ์ด๋ฅผ ์ด๊ธฐํ ํ๋ ๊ฒ์ ๋ค์ฐจ์ ์ด๋ ์ด๋ฅผ ์ด๊ธฐํํ๋ ๊ฒ๊ณผ ๊ฑฐ์ ๋์ผํ๋ค.
๊ตฌ์กฐ์ฒด ์ด๋ ์ด๋ฅผ ์ด๊ธฐํํ๋ ์ด์ ์ค ํ๋๋ ์ด๋ฅผ ์คํ ์ค ๊ฐ์ด ๋ณํ์ง ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ทจ๊ธํ๊ธฐ ์ํด์ ์ด๋ค.
๐ ๊ตฌ์กฐ์ฒด๋ฅผ ์ด์ฉํ์ฌ ๊ตญ๊ฐ๋ฒํธ ์ ์ฅํ๊ธฐ
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' };
์ฐฝ๊ณ ์ ๋จ์์๋ ๋ถํ๋ค์ ํ์ํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํด๋ณด์
๋ค์ด๊ฐ ์ ๋ณด๋ ๋ถํ ๋ฒํธ, ์ด๋ฆ, ์๋์ด๋ค.
์๋ก์ด ๋ถํ ๋ฒํธ, ์ด๋ฆ, ๋จ์ ์๋์ ์ถ๊ฐํ ์ ์๋๋ก ํ๋ค. ๋ง์ฝ ์ด๋ฏธ ํด๋น ๋ถํ์ด ์๊ฑฐ๋ ๊ฐ๋์ฐฌ ๊ฒฝ์ฐ ์๋ฌ ๋ฉ์ธ์ง๋ฅผ ์ถ๋ ฅํ๋ค.
๋ถํ ๋ฒํธ๊ฐ ์ฃผ์ด์ง๋ฉด ์ด๋ฆ, ๋จ์ ์๋์ ์ถ๋ ฅํ ์ ์๋๋ก ํ๋ค. ๋ง์ฝ ํด๋น ๋ถํ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์๋ค๋ฉด ์๋ฌ ๋ฉ์ธ์ง๋ฅผ ์ถ๋ ฅํ๋ค.
๋ถํ ๋ฒํธ๊ฐ ์ฃผ์ด์ง๋ฉด ๋จ์ ์๋์ ๋ณ๊ฒฝํ ์ ์๋๋ก ํ๋ค. ๋ง์ฝ ํด๋น ๋ถํ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์๋ค๋ฉด ์๋ฌ ๋ฉ์ธ์ง๋ฅผ ์ถ๋ ฅํ๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ด๊ธด ์ ๋ณด ์ ์ฒด๋ฅผ ์ถ๋ ฅํ ์ ์๋๋ก ํ๋ค. ์ ๋ ฅํ ์์๋๋ก ์ถ๋ ฅ๋๋๋ก ํ๋ค.
ํ๋ก๊ทธ๋จ ์คํ ์ข ๋ฃ
์ด ํ๋๋ค์ ํ๊ธฐ ์ํด 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;
}
๊ณต์ฉ์ฒด(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 };
์๋์ ์ ๋ฌผ ๋ชฉ๋ก์ ์ ์ฅํ๊ณ ์ ํ ๋,
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" */
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;
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);
}
๋ง์ ํ๋ก๊ทธ๋จ์์, ๋จ์ง ์์ ์๋ฏธ ์๋ ๊ฐ๋ค์ ์งํฉ๋ง์ ๊ฐ์ง ๋ณ์๋ค์ด ํ์ํ ๊ฒ์ด๋ค.
์๋ฅผ ๋ค์ด ์นด๋ ๊ฒ์์์ ์นด๋๋ช
์ ์ ์ฅํ๋ ๋ณ์๋ "ํด๋ก๋ฒ" "๋ค์ด์๋ชฌ๋" "ํํธ" "์คํ์ด๋" 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;
์ด๊ฑฐํ์ด ํจ์ ๋ด๋ถ์์ ์ ์ธ๋๋ฉด ํด๋น ์์๋ ํจ์ ์ธ๋ถ์์ ์ฌ์ฉํ ์ ์๋ค.
๊ตฌ์กฐ์ฒด, ๊ณต์ฉ์ฒด์ ํจ๊ป ์ด๊ฑฐํ์ ์ด๋ฆ์ ์ง์ ๋๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค. 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;
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๋ฅผ ์ ์์ฒ๋ผ ๋ค๋ฃฌ๋ค.
์์ 16.4 ์ ์์ ๋ค๋ฃจ์๋, ์ต๊ทผ์ ์์ ๋ ๊ฐ๋ค์ ํ์
ํ๋๋ฐ ์ด๊ฑฐํ์ ํจ๊ณผ์ ์ด๋ค.
์๋ฅผ ๋ค์ด kind ๋ณ์๋ฅผ int ๋์ ์ด๊ฑฐํ์ผ๋ก ๋ง๋ค๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
๐ ์ด๊ฑฐํ์ ์ด์ฉํด kind ๋ง๋ค๊ธฐ
typedef struct {
enum {INT_KIND, DOUBLE_KIND} kind;
union {
int i;
double d;
} u;
} Number;