C 언어포인터정복하기 16 강. 포인터로자료구조화하기 TAE-HYONG KIM COMPUTER ENG, KIT
2 학습내용 구조체멤버와구조체포인터멤버 다른구조체 ( 변수 ) 를가리키는구조체 ( 변수 ) 연결된리스트 의구성및관리 포인터로 연결된리스트 탐색하기
3 중첩구조체에자료저장하기 중첩된구조체변수에값저장하기 struct person { char PRID[15]; char name[9]; struct car { char CRID[10]; char model[20]; int pyear; struct person owner; 만약멤버구조체 ( 변수값 ) 를독립적으로사용하거나중복해서사용하려면자료가중복저장되어야한다 해결책은? 저장하지말고가리켜라! struct person person1 = { 800101-1234567, 홍길동 struct car car1 = { 12 가 3456, 소나타, 2013, car2; printf( %u, sizeof(car1)); car1.owner = person1; car2.owner = person1; printf( %u %u, &person1, &car1); person1 PRID 홍길동 car1 CRID 소나타 pyear PRID 홍길동 name car2 CRID model pyear PRID name 홍길동
4 구조체포인터멤버사용하기 구조체포인터멤버로구조체연결하기 struct person { char PRID[15]; char name[9]; struct car { char CRID[10]; char model[20]; int pyear; struct person *owner; 저장공간을절약할수있다 자료를관계형으로구조화할수있다. 구조체간관계가복잡하면자료의이해와접근이어려워진다 struct person person1 = { 800101-1234567, 홍길동 struct car car1 = { 12 가 3456, 현대소나타, 2013, car2; printf( %u, sizeof(car1)); car1.owner = &person1; car2.owner = &person1; printf( %s, car1.owner->name); person1 PRID 홍길동 car1 CRID 소나타 pyear owner car2 CRID model pyear owner
5 구조체가서로연결될수있나? 친구관계를연결된구조체로구현해보자 struct student { char stid[9]; char name[9]; struct student *friend; // struct student *friends[n]; struct student stu1 = { 김모군, 20141111 Struct student stu2 = { 이모군, 20142222 Struct student stu3 = { 박모군, 20143333 stu1.friend = &stu2; stu2.friend = &stu3; stu3.friend = &stu2; 연결리스트 (linked list) stu1 1111 김모군 stu2 2222 이모군 stu3 3333 박모군 김모군의친구의친구는? friend friend friend printf( %s, stu1.friend->name); printf( %s, stu1.friend->friend->name);
6 연결리스트의종류 선형연결리스트 word1 word2 boy girl next next word3 man NULL struct Wnode { char word[20]; struct Wnode *next; word1, word2, word3; strcpy(word1.word, boy ); strcpy(word1.word, girl ); strcpy(word1.word, man ); 트리구조의리스트 term1 + left right term2 term3 a b left left right right word1.next = &word2; word2.next = &word3; word3.next = NULL; struct BTnode { char symbol; struct BTnode *left; struct BTnode *right; term1={0, term2={0, term3={0 term1.symbol = + ; term1.left = &term2; term1.right = &term3; term2.symbol = a ; Term3.symbol = b ;
7 선형연결리스트의구성 (1) 리스트의생성 노드의동적생성 메모리동적할당이용 노드의처음위치와끝위치를관리 ( 각각 head, tail 포인터 ) 삽입과삭제의위치는리스트의종류 ( 큐 (FIFO), 스택 (LIFO)) 에따라결정 패턴 23-1 선형연결리스트의구성 ( 단어장구조 ) #include <stdio.h> #include <string.h> #include <stdlib.h> typedef struct Wnode { char word[20]; char meaning[20]; struct Wnode *next; WNODE; // for strcmp() // for malloc(), free() // 단어 // 단어의뜻 int main(void) { WNODE *head = NULL; // 연결리스트의시작노드를가리킴 WNODE *tail = NULL; // 연결리스트의삽입위치 ( 끝 ) 을가리킴 int sel; // 선택메뉴저장...
8 선형연결리스트의구성 (2) 패턴 23-2 선형연결리스트의구성 ( 단어장메뉴 ) do { printf(" 선택하세요 (1. 추가, 2. 삭제, 3. 검색, 4. 출력, 5. 종료 ): "); scanf("%d", &sel); fflush(stdin); switch (sel) { case 1: // 단어추가 리스트뒤에추가 tail = addword(tail); // tail 포인터갱신 if (head == NULL) // 단어가없었던경우 head = tail; // head를갱신된 tail위치로 break; case 2: // 단어삭제 리스트앞에서삭제 head = deleteword(head); // head 포인터갱신 if (head == NULL) // 단어모두삭제시 break; case 3: tail = NULL; searchword(head); // tail 포인터초기화 // 리스트앞에서부터검색 break; case 4: printword(head); // 리스트앞에서부터출력 break; while (sel!= 5); // 종료선택시반복문탈출 return 0;
9 선형연결리스트의처리 패턴 23-3 선형연결리스트의처리 ( 단어추가, 삭제 : 큐방식 ) WNODE *addword(wnode *in) { if (in == NULL) // 단어가하나도없을경우 in = (WNODE *)malloc(sizeof(wnode)); // 단어메모리할당 else { in->next = (WNODE *)malloc(sizeof(wnode)); // 다음노드생성 in = in->next; // 생성노드로위치이동 printf(" 단어를입력하세요 : "); fgets(in->word, sizeof(in->word), stdin); printf(" 단어의뜻을입력하세요 : "); fgets(in->meaning, sizeof(in->meaning), stdin); in->next = NULL; // 생성노드마감 return in; // 생성노드위치반환 WNODE *deleteword(wnode *out) { WNODE *delete = out; // 삭제할단어가리키는임시포인터 if (out!= NULL) { // 삭제할단어가있는경우 printf(" 삭제되는단어 : %s", out->word); out = out->next; // head 위치이동위해 free(delete); // 삭제하는단어메모리반환 else // 삭제할단어가없는경우 puts(" 삭제할단어가없습니다 "); return out; // 새로운 head 위치반환
10 선형연결리스트의탐색 패턴 23-4 선형연결리스트의탐색 ( 단어검색과출력 ) void searchword(wnode *start) { WNODE *search = start; // 탐색포인터생성및초기화 char Sword[20]; // 탐색단어저장배열 printf(" 뜻을알고자하는단어를입력하세요 : "); fgets(sword, sizeof(sword), stdin); while (search!= NULL) // 리스트의끝까지탐색 if (!strcmp(sword, search->word)) { // 탐색단어가맞으면 printf(" 찾는단어 : %s", Sword); printf(" 단어의뜻 : %s\n", search->meaning); return; else // 탐색단어가아니면 search = search->next; // 다음단어로이동 printf(" 입력한단어가없습니다.\n"); void printword(wnode *start) { WNODE *print = start; // 출력포인터생성및초기화 int Wcount = 0; // 단어개수저장변수 while (print!= NULL) { // 리스트의끝까지탐색 printf("[%d] 단어 : %s", ++Wcount, print->word); printf("[%d] 의미 : %s\n", Wcount, print->meaning); print = print->next; // 다음단어로이동 printf(" 총 %d개의단어가있습니다 \n", Wcount);
11 C 포인터정복하기를마치면서 C 포인터정복은이제시작이다 예제를실행해보고무수히변형해보자 예제를확장해보자 작은과제를만들어보자 좀더큰과제 ( 작품 ) 에도전해보자