1 16 유도 자료형 학기
Perfect C 2 구조체 (struct) 구조체의 필요성 책에 대한 정보를 살펴보면 매우 다양 struct 서로 다른 자료형의 변수들을 묶어서 만든 하나의 새로운 자료형을 구조체 (struct) 구조체는 연관된 멤버로 구성되는 통합 자료형으로 대표적인 유도자료형 구조체 정의 중괄호 사이에 원하는 여러 개의 변수를 선언 중괄호 다음 마지막에 세미콜론 (;) 을 반드시 기술 책 정보 제목, 저자, 출판사, 페이지수, 가격, ISBN 등
Perfect C 3 구조체 정의와 변수 선언 구조체 정의 구조체 멤버 ( 구성요소, member) 구조체 정의 구문에서는 각 구성요소의 초기값을 대입할 수 없음 한 구조체 내부에서 선언되는 구조체 멤버의 이름은 모두 유일해야 함 구조체의 정의는 구조체 struct book 을 새로운 자료형으로 정의하는 구문 구조체 정의는 구조체 변수를 선언하는 구문이 아님 변수 선언 구조체 정의 구문은 변수의 범위와 비슷 구조체 정의 구문의 위치에 따라 구조체 선언 시 자료형 이용의 범위가 정해짐
Perfect C 4 구조체 정의와 변수 선언 구조체 변수를 선언하는 다른 방법은 다음과 같이 구조체 정의와 변수 선언을 함께하는 방법 위 구문에서 변수 yourbook 과 mybook 은 모두 같은 구조체 struct book 자료형 위 구조체 정의 구문에서 구조체 태그 이름 book 을 생략해도 구조체 변수 선언이 가능
Perfect C 5 자료형이 다른 구조체 다음 구문에서 구조체 변수 mybook 과 yourbook 은 자료형이 다른 변수 즉 동일한 구조체 태그 이름으로 선언된 변수만이 동일한 자료형의 구조체가 됨 자료형이 다르면 대입연산자를 사용 불가능
Perfect C 6 typedef 를 이용한 형 선언 typedef 를 이용한 형 선언 구조체 struct book 이 정의된 상태에서 구조체 struct book 좀 더 간단하게 선언 typedef 로 구조체 정의 구조체 정의 자체를 typedef 와 함께하는 방법 아래 typedef 구문에서 새로운 자료형으로 정의되는 키워드는 software 로서, 이 구문 이후에는 구조체를 선언할 때 software 를 이용하여 형의 선언이 가능 struct book { char title[50]; // 제목 char author[50]; // 저자 char publish[50]; // 출판사 int pages; // 페이지수 int price; // 가격 }; typedef struct book book ; … book yourbook; book mybook;
Perfect C 7 초기 값 지정 구조체 struct book 정의 구조체 정의에서는 구조체 멤버에 초기 값을 지정 불가능 구조체 변수 mybook 에 초기 값을 대입 구조체 변수도 배열과 같이 중괄호를 이용하여 초기 값을 대입 가능 멤버 참조 구조체 멤버를 접근하기 위해서는 멤버 접근 연산자인 마침표 (.) 를 이용 struct book { … int pages = 200; int price = 30000; }; typedef struct book book; 구조체 정의에서 멤버의 초기 값을 저장하는 것은 허용되지 않는다. book mybook = " 강 환수 ", " 학술정보 ", 530, 20000}; 구조체변수. 구조체멤버 mybook.author
Perfect C 8 예제 소스 structbook.c 구조체 정의, 변수 선언, 구조체 이용 프로그램 예제 16-3 (568 쪽 )
Perfect C 9 중간점검 : 문제점은 ? struct student { char name[30]; int height; int weight; char name; }; struct student s1; typedef struct student { char name[30]; int height; int weight; }; struct rectangle { double width; double height; }; typedef rectangle rect; struct rectangle { int width = 100; int height = 20; } r; struct rectangle { int width; int height; } r; r.width = 100; r.height = 20;
Perfect C 10 복소수 구조체 복소수를 표현하는 구조체 complex 를 정의 복소수는 a+bi 로 표현되며, 실수부 a 와 허수부 b 는 실수 값 구조체 struct complex 는 다음과 같이 정의 struct complex { double real; // 실수 double img; // 허수 }; typedef struct complex complex;
Perfect C 11 구조체 주의 메인 함수 상단 전역 부분에서 struct complex 를 정의 메인 함수 내부에서 다시 같은 이름으로 struct complex 를 정의하면서 변수 comp 를 하나 선언 두 변수 comp1 과 comp2 는 다시 complex 유형으로 선언 comp = comp2; 와 같은 대입문은 에러
Perfect C 12 구조체 포인터 구조체 변수를 가리키는 주소 값을 저장하려면 구조체 포인터 변수를 이용 변수 ku 는 구조체 변수이고, 변수 ptr 은 구조체를 가리키는 포인터 struct univ { char title[50]; // 이름 char address[50]; // 주소 int students; // 학생수 }; struct univ ku = {" 한국대학교 ", " 서울시 서초구 ", 5000}; struct univ *ptr = &ku;
Perfect C 13 구조체 포인터 이용 연산자 -> 구조체 포인터 변수 ptr 을 이용하여 구조체의 멤버를 참조하려면 연산자 -> 를 이용 연산자 -> 는 구조체 멤버 참조 연산자로서 연산자 우선순위가 가장 높음 간접 연산자 * 변수 ptr 을 이용하여 구조체의 멤버 member 를 참조하는 다른 방법은 (*ptr).member 를 이용하는 방법 위 구문에서 (*ptr).title 은 *ptr.title 과는 다른 의미이므로 반드시 괄호를 사용 *ptr.title 은 *(ptr.title) 을 의미하므로 ptr 이 포인터 변수이면 에러가 발생 구조체의 멤버를 참조하는 연산자 -> 와. 의 연산자 우선순위가 가장 높기 때문 printf(" 학교 : %s, 주소 : %s, 학생수 : %d\n", ptr->title, ptr->address, ptr->students); printf(" 학교 : %s, 주소 : %s, 학생수 : %d\n", (*ptr).title, (*ptr).address, (*ptr).students);
Perfect C 14 포인터 변수 구조체 변수 및 포인터 변수를 이용하는 다음 4 가지 구문을 잘 구별하도록
Perfect C 15 구조체 배열 구조체 변수를 여러 개 선언하기 위해서 구조체 배열을 이용 구조체 book 으로 배열 clang[3] 을 선언하여 구조체 원소 3 개를 선언하는 구문 다른 배열과 같이 구조체 배열도 첨자를 이용하여 각 원소를 참조하며, 첨자는 0 부터 ( 배열크기 -1) 까지 가능 첫 구조체 원소의 멤버를 출력하는 구문 struct book { char author[50]; char title[50]; int pages; }; struct book clang[3] = { {"Deitel", "C How To Program", 600}, {"Al Kelly", "A Book On C", 700}, {"Stephen Prata", "C Primer Plus", 800} }; printf(" 저자 : %s, 제목 : %s, 페이지수 : %d\n", clang[0].author, clang[0].title, clang[0].pages);
Perfect C 16 구조체 인자, 값 전달 복소수 연산에 이용되는 함수를 구현 함수 paircomplex1() 는 전달 인자 복소수의 켤레 복소수를 구하여 반환하는 함수 그러므로 변수 pcomp 에는 {3.4, -4.8} 이 저장 구현 위와 같이 구조체는 함수의 전달 인자와 반환 값으로 이용이 가능 위 함수는 구조체 인자를 값에 의한 호출 (call by value) 방식으로 이용 즉 함수 paircomplex1() 내부에서 지역 구조체 변수 com 을 하나 만들어 실인자의 구조체 값을 모두 복사하는 방식으로 구조체 값을 전달 complex comp = {3.4, 4.8}; complex pcomp; pcomp = paircomplex1(comp); complex paircomplex1(complex com) { com.img = -com.img; return com; }
Perfect C 17 구조체 인자, 주소 전달 인자를 call by address 로 이전 함수를 주소에 의한 호출 (call by address) 방식으로 변환 다음 함수 paircomplex2() 는 인자를 주소 값으로 저장하여, 실인자의 변수 comp 의 값을 직접 수정하는 방식 위 함수를 호출하기 위해서는 comp 의 주소 값을 이용해야 하므로 다음과 같이 호출 구조체가 많은 멤버를 가지거나, 큰 배열을 멤버로 가지는 경우, 구조체 자체를 인자로 전달하는 것은 매우 비효율 이러한 경우는 주소 값으로 전달하는 방식인 주소에 의한 호출 방식이 효율적 void paircomplex2(complex *com) { com->img = -com->img; } paircomplex2(&comp);
Perfect C 18 예제 소스 예제 16-7(578 쪽 ) complexfunction.c 함수 paircomplex1() 과 paircomplex2() 를 구하는 프로그램
Perfect C 19 공용체 정의 공용체는 서로 다른 자료형을 동일한 저장 공간에 이용하는 자료형 공용체 union data 를 정의하는 구문 구조체 정의에서 키워드 struct 를 union 으로 사용한 것과 비슷 공용체의 멤버는 모든 멤버가 동일한 저장 공간을 사용하므로 동시에 여러 멤버의 값을 저장하여 이용할 수 없으며, 마지막에 저장한 하나의 멤버의 자료 값만을 저장 공용체 union data 정의와 함께 변수 data1 과 포인터 변수 pdata 를 선언하는 구문 union data { char ch; int cnt; double real; }; union data { char ch; int cnt; double real; } data1, *pdata ;
Perfect C 20 공용체 메모리 내부 메모리 공용체 union data 자료형의 변수 data1 은 멤버의 유형이 char, int, double 이므로 멤버 중 가장 큰 크기인 double 형의 8 바이트를 공용체의 저장공간으로 확보하여 세 개의 멤버가 함께 이용 동일한 저장장소를 함께 이용 멤버가 char 인 경우는 8 바이트 중에서 첫 1 바이트만 이용하고, int 인 경우는 전체 공간의 첫 4 바이트만 이용하며, double 인 경우는 8 바이트 공간을 모두 사용 union data { char ch; int cnt; double real; } data1, *pdata ;
Perfect C 21 공용체 이용 구조체와 같이 typedef 를 이용하여 새로운 자료형으로 정의 구조체의 초기값은 첫 멤버의 초기 값으로만 저장이 가능하고 다른 동일한 변수의 값으로 초기화 가능 공용체 변수로 멤버를 접근하기 위해서는 구조체와 같이 접근 연산자 ‘.’ 을 이용하며, 포인터인 경우는 연산자 ‘->’ 를 이용 공용체 변수 data1 의 멤버 ch 에 문자 ‘a’ 를 저장하는 구문 이 문장 이후에 멤버 cnt 나 real 을 출력하는 것은 의미가 없음 typedef union data uniondata; //uniondata data1 = {10}; // 에러 발생 uniondata data2 = {'A'}; // 첫 멤버인 char 유형으로만 초기화 가능 uniondata data3 = data2; // 다른 변수로 초기화 가능 pdata = &data2; printf("%2c %2c\n", pdata->ch, (*pdata).ch); printf("%2c %2c\n", data2.ch, data3.ch); data1.ch = 'a'; printf("%c, %d, %6.2f\n", data1.ch, data1.cnt, data1.real);
Perfect C 22 열거형 키워드 enum 을 이용하여 열거형을 정의 열거형 구문은 관련 있는 정수형 상수 목록 집합을 정의하는 구문 위 문장은 변수 col 을 열거형 enum color 로 선언하는 구문 열거형 enum color 는 색상을 나타내는 5 개의 상수 yellow, red, blue, magenta, green 을 표현하는 의미 color 는 열거형 태그이름으로 다음과 같이 생략 가능 정수 상수에 대응 5 개의 상수 yellow, red, blue, magenta, green 은 각각 0 에서부터 4 까지의 정수 상수에 대응 정수 상수는 변수 col 에 대입할 수 있고, 상수 0 에 해당하는 값을 표현 enum color {yellow, red, blue, magenta, green} col; col = yellow; enum {yellow, red, blue, magenta, green} col;
Perfect C 23 열거형 이용 enum day7 을 정의하고, typedef 를 이용하여 새로이 열거형 자료형 day 를 정의하는 구문 새로운 자료형 day 는 enum day7 로 변수 선언에 다음과 같이 이용할 수 있고, 변수를 선언하면서 초기 값으로 상수 fri 를 대입하는 문장 열거형 day 는 7 개의 상수 sun, mon, tue, wed, thu, fri, sat 를 가지며, 각각 0 에서부터 6 까지의 정수 상수에 대응 열거형 enum pl 정의에서는 필요한 경우, 상수 값을 각 상수에 지정 가능 다음은 circle 상수는 0, tri 는 3, rect 는 4, star 는 7, dia 는 8 로 정의 즉 상수 값을 지정한 상수는 그 값으로, 지정되지 않은 상수는 그 이후로 1 씩 증가한 상수 값으로 정의 enum day7 {sun, mon, tue, wed, thu, fri, sat}; typedef enum day7 day; enum pl {c=1972, cpp=1983, java=1995, cs=2000}; typedef enum pl plang; day today = fri; enum shape {circle, tri=3, rect=4, star=7, dia}; typedef enum shape shape;
Perfect C 24 프로그래밍 실습 프로그램 목적 이 장에서 배운 구조체와 열거형을 이용하여 카드 게임을 할 수 있는 여러 자료형을 만들어보고, n 명에게 7 장의 카드를 나눠주는 프로그램을 작성 카드 게임 카드는 52 장이고, 모양은 4 가지 hearts, diamonds, clubs, spades 이며, 번호는 ace(1) 부터 10 까지 그리고 jack(11), queen(12), king(13) 의 종류 출력
Perfect C 25 구현 프로그램에 필요한 구조체 정의나 열거형 정의는 모두 파일 card.h 헤더파일에 코딩 파일 card.c 에는 다음 함수 네 개를 구현 int main() { card deck[52]; … return 0; } void filldeck(card *deck) // 모든 카드에 모양과 번호를 부여 { … } void shuffle(card *deck) // 카드를 섞는 과정 { … } void deal(card *deck, int cnt) //cnt 에게 7 장을 나누어 줌 { … }
Perfect C 26 헤더 파일 card.h 카드의 모양과 번호를 열거형 enumsuit 와 enumface 로 정의하고, 구조체 card 의 멤버로 번호와 모양을 저장하는 suit, face 를 정의 구조체 자료형 card 를 typedef 를 이용하여 정의 문자열 배열은 번호나 모양의 출력을 위하여 전역 변수로 선언 함수 세 개의 함수원형
Perfect C 27 메인 함수 메인 함수에서는 카드의 수만큼 배열 deck[52] 를 선언하여 이 배열을 함수 filldeck(), shuffle(), deal() 의 인자로 이용 card deck[52]; int cnt = 2; filldeck(deck); shuffle(deck); printf(" 카드 게임에 몇 사람이 참가합니까 ? >> "); scanf("%d", &cnt); printf("\n"); deal(deck, cnt); return 0;
Perfect C 28 함수 deal() 함수 deal() 의 두 번째 인자는 게임에 참가하는 인원 수로 표준입력으로 받은 값을 실인자로 호출 출력될 문자열은 문자 포인터 배열 strface[13] 과 strsuit[4] 에 정의 카드 deck[i] 에는 멤버인 face 와 suit 가 있으며, 이 값은 카드 모양의 열거형 정수 상수 값으로 정의되어 있으므로 출력될 문자열로 strface[deck[i].face] 와 strsuit[deck[i].suit] 를 이용하면 쉽게 원하는 문자열 출력 가능 void deal(card *deck, int cnt) { … for ( i = 0; i < total; i++ ) printf( "%5s of %-8s%c", strface[deck[i].face], strsuit[deck[i].suit], (i+1) % cnt ? ' ' : '\n'); }