2015-1 프로그래밍언어 8. 구조체 (Structure) 2015 년 4 월 11 일 교수김영탁 영남대학교공과대학정보통신공학과 (Tel : +82-53-810-2497; Fax : +82-53-810-4742 http://antl.yu.ac.kr/; E-mail : ytkim@yu.ac.kr)
Outline 구조체란무엇인가? 구조체의선언, 초기화, 사용 구조체의활용 구조체의배열 구조체와포인터 구조체와함수 공용체 열거형 typedef Bit-field 구조체 8-2
자료형의분류 기본자료형 : char, int, float, double 등 자료형 파생자료형 : 배열 (array), 열거형 (enum), 구조체 (struct), 공용체 (union) 8-3
구조체의필요성 학생에대한데이터를하나로모으려면? 학번 : 20100001( 정수 ) 이름 : 최자영 ( 문자열 ) 학점 : 4.3( 실수 ) int number; char name[10]; double grade; 와같이개별변수로 나타낼수있지만 묶을수가있나? 8-4
구조체의필요성 int number; char name[10]; double grade; 구조체를사용하면변수들을하나로묶을수있습니다. 8-5
구조체와배열 구조체 vs 배열 int data[50]; struct student { int st_id; char name[50]; double avg_score;.... } 같은자료유형의집합 8-6 다른자료유형의집합
구조체선언 구조체선언형식 struct 태그 { 자료형멤버1; 자료형멤버2;... 8-7
구조체선언 구조체선언은변수선언은아님 구조체를정의하는것은와플이나붕어빵을만드는틀을정의하는것과같다. 와플이나붕어빵을실제로만만들릭위해서는구조체변수를선언하여야한다. 구조체 구조체변수 8-8
구조체선언의예 // x값과 y값으로이루어지는화면의좌표 struct point { int x; // x 좌표 int y; // y 좌표 // 복소수 struct complex { double real; double imag; // 날짜 struct date { int month; int day; int year; // 실수부 // 허수부 // 사각형 struct rect { int x; int y; int width; int grade; // 직원 struct employee { char name[20]; int age; int gender; int salary; // 이름 // 나이 // 성별 // 월급 8-9
구조체변수선언 구조체정의와구조체변수선언은다르다. 8-10
구조체의초기화 중괄호를이용하여초기값을나열한다. struct student { int number; char name[10]; double grade; struct student s1 = { 24, "Kim", 4.3 8-11
구조체멤버참조 구조체멤버를참조하려면다음과같이. 연산자를사용한다. s1.number = 26; strcpy(s1.name, "Kim"); s1.grade = 4.3; // 정수멤버 // 문자열멤버 // 실수멤버.. 기호는구조체에서멤버를참조할때사용하는연산자입니다. 8-12
예제 #1 struct student { int number; char name[10]; double grade; int main(void) { struct student s; s.number = 20070001; strcpy(s.name," 홍길동 "); s.grade = 4.3; 구조체선언 구조체변수선언 구조체멤버참조 printf(" 학번 : %d\n", s.number); printf(" 이름 : %s\n", s.name); printf( 학점 : %f\n", s.grade); return 0; } 학번 : 20070001 이름 : 홍길동학점 : 4.300000 8-13
예제 #2 struct student { int number; char name[10]; double grade; 구조체선언 int main(void) { struct student s; printf(" 학번을입력하시오 : "); scanf("%d", &s.number); 구조체변수선언 구조체멤버의주소전달 } printf(" 이름을입력하시오 : "); scanf("%s", s.name); printf(" 학점을입력하시오 ( 실수 ): "); scanf("%lf", &s.grade); printf(" 학번 : %d\n", s.number); printf(" 이름 : %s\n", s.name); printf(" 학점 : %f\n", s.grade); return 0; 8-14 학번을입력하시오 : 20070001 이름을입력하시오 : 홍길동학점을입력하시오 ( 실수 ): 4.3 학번 : 20070001 이름 : 홍길동학점 : 4.300000
#include <math.h> struct point { int x; int y; int main(void) { struct point p1, p2; int xdiff, ydiff; double dist; 예제 #3 점의좌표를입력하시오 (x y): 10 10 점의좌표를입력하시오 (x y): 20 20 두점사이의거리는 14.142136 입니다. p2 (x,y) printf(" 점의좌표를입력하시오 (x y): "); scanf("%d %d", &p1.x, &p1.y); p1 (x,y) printf(" 점의좌표를입력하시오 (x y): "); scanf("%d %d", &p2.x, &p2.y); xdiff = p1.x - p2.x; ydiff = p1.y - p2.y; dist = sqrt(xdiff * xdiff + ydiff * ydiff); } printf(" 두점사이의거리는 %f 입니다.\n", dist); return 0; 8-15
구조체를멤버로가지는구조체 struct date { int year; int month; int day; // 구조체선언 struct student { // 구조체선언 int number; char name[10]; struct date dob; // date of birth, 구조체안에구조체포함 double grade; struct student s1; // 구조체변수선언 s1.dob.year = 1983; s1.dob.month = 03; s1.dob.day = 29; // 멤버참조 8-16
예제 #include <stdio.h> struct point { int x; int y; struct rect { struct point p1; struct point p2; int main(void) { struct rect r; int w, h, area, peri; p1(x,y) p2(x,y) 8-17
예제 printf(" 왼쪽상단의좌표를입력하시오 : "); scanf("%d %d", &r.p1.x, &r.p1.y); p1(x,y) printf(" 오른쪽상단의좌표를입력하시오 : "); scanf("%d %d", &r.p2.x, &r.p2.y); w = r.p2.x - r.p1.x; h = r.p2.x - r.p1.x; p2(x,y) area = w * h; peri = 2 * w + 2 * h; printf(" 면적은 %d 이고둘레는 %d 입니다.\n", area, peri); } return 0; 왼쪽상단의좌표를입력하시오 :11 오른쪽상단의좌표를입력하시오 :66 면적은 25 이고둘레는 20 입니다. 8-18
구조체변수의대입과비교 같은구조체변수까리대입은가능하지만비교는불가능하다. struct point { int x; int y; int main(void) { struct point p1 = {10, 20 struct point p2 = {30, 40 p2 = p1; // 대입가능 if( p1 == p2 ) // 비교 -> 컴파일오류!! printf("p1 와 p2 이같습니다.") } if( (p1.x == p2.x) && (p1.y == p2.y) ) printf("p1와 p2이같습니다.") // 올바른비교 8-19
구조체배열 (Array of Struct) 구조체를여러개모은것 8-20
구조체배열의선언 구조체배열 (Array of Struct) struct student { int number; char name[20]; double grade; int main(void) { struct student list[100]; // 구조체의배열선언 } list[2].number = 27; strcpy(list[2].name, " 홍길동 "); list[2].grade = 178.0; 8-21
구조체배열의초기화 구조체배열의초기화 struct student list[3] = { { 1, "Park", 172.8 }, { 2, "Kim", 179.2 }, { 3, "Lee", 180.3 } 8-22
구조체배열예제 #define SIZE 3 struct student { int number; char name[20]; double grade; int main(void) { struct student list[size]; int i; for(i = 0; i < SIZE; i++) { printf(" 학번을입력하시오 : "); scanf("%d", &list[i].number); printf(" 이름을입력하시오 : "); scanf("%s", list[i].name); printf(" 학점을입력하시오 ( 실수 ): "); scanf("%lf", &list[i].grade); } 학번을입력하시오 : 20070001 이름을입력하시오 : 홍길동학점을입력하시오 ( 실수 ): 4.3 학번을입력하시오 : 20070002 이름을입력하시오 : 김유신학점을입력하시오 ( 실수 ): 3.92 학번을입력하시오 : 20070003 이름을입력하시오 : 이성계학점을입력하시오 ( 실수 ): 2.87 학번 : 20070001, 이름 : 홍길동, 학점 : 4.300000 학번 : 20070002, 이름 : 김유신, 학점 : 3.920000 학번 : 20070003, 이름 : 이성계, 학점 : 2.870000 } for(i = 0; i< SIZE; i++) printf(" 학번 : %d, 이름 : %s, 학점 : %f\n", list[i].number, list[i].name, list[i].grade); return 0; 8-23
구조체배열의응용예 (1) Can initialize at declaration Example: struct Planet { char name[10]; double relativemass; double distance; struct Planet earth = { Earth, 1.0, 150 Declaration provides initial data to all three member variables 8-24
Array of Structure Struct data elements can be organized in array Example) struct Planet solarsystem[solar_planets] = { {"Mercury", 0.0558, 57.9}, {"Venus", 0.815, 108}, {"Earth",1.0, 150}, {"Mars", 0.107, 228}, {"Jupiter", 318, 778}, {"Saturn", 95.1, 1430}, {"Uranus", 14.5, 2870}, {"Neptune", 17.2, 4500}, {"Pluto", 0.11, 5900} 8-25
Handling attributes of each element of struct array void printplanets(struct Planet solarplanets[], int num_planet) 1. { 2. for (int i = 0; i<num_planet; i++) 3. { 4. printf("%2d", i); 5. printf(" Name: "); 6. printf("%-8s", solarplanets[i].name); 7. printf(" Rel Mass: "); 8. printf("%7.3f", solarplanets[i].relativemass); 9. printf(" Dist from Sun: "); 10. printf("%6.1f n", solarplanets[i].distance); 11. } // end for 12.} 8-26
Sorting Array of Structure Sorting elements in array of structure (1) void sortplanetsbyrelmass(struct Planet solarplanets[], int num_planet) 1. { 2. struct Planet temp; 3. int i, j, m; 4. double min_relmass; 5. for (i=0; i<num_planet-1; i++) { 6. m = i; 7. min_relmass = solarplanets[i].relativemass; 8. for (j=i+1; j<num_planet; j++) { 9. if (min_relmass > solarplanets[j].relativemass) { 10. m = j; 11. min_relmass = solarplanets[j].relativemass; 12. } 13. } // end inner for 14. if (m!= i) { // if new minimum found, swap 15. temp = solarplanets[i]; 16. solarplanets[i] = solarplanets[m]; 17. solarplanets[m] = temp; 18. } 19. } // end outer for 20. } 8-27
Sorting elements in array of structure (2) void sortplanetsbyname(struct Planet solarplanets[], int num_planet) { 1. struct Planet temp; 2. int i, j, m; 3. char min_name[10] = {0 4. for (i=0; i<num_planet-1; i++) { 5. m = i; 6. strcpy(min_name, solarplanets[i].name); 7. for (j=i+1; j<num_planet; j++) { 8. if (strcmp(min_name, solarplanets[j].name) > 0) { 9. m = j; 10. strcpy(min_name, solarplanets[j].name); 11. } 12. } // end inner for 13. if (m!= i) { // if new minimum found, swap 14. temp = solarplanets[i]; 15. solarplanets[i] = solarplanets[m]; 16. solarplanets[m] = temp; 17. } 18. } // end outer for 19.} 8-28
1. int main() { 2. struct Planet solarsystem[solar_planets] = 3. {{"Mercury", 0.0558, 57.9}, {"Venus", 0.815, 108}, {"Earth",1.0, 150}, 4. {"Mars", 0.107, 228}, {"Jupiter", 318, 778}, {"Saturn", 95.1, 1430}, 5. {"Uranus", 14.5, 2870}, {"Neptune", 17.2, 4500}, {"Pluto", 0.11, 5900} 6. printf(" n Initial state n"); 7. printplanets(solarsystem, SOLAR_PLANETS); 8. sortplanetsbyrelmass(solarsystem, SOLAR_PLANETS); 9. printf(" n After sorting by relative mass: n"); 10. printplanets(solarsystem, SOLAR_PLANETS); 11. sortplanetsbydist(solarsystem, SOLAR_PLANETS); 12. printf(" n After sorting by distance from sun: n"); 13. printplanets(solarsystem, SOLAR_PLANETS); 14. sortplanetsbyname(solarsystem, SOLAR_PLANETS); 15. printf(" n After sorting by name using strcmp and strcpy: n"); 16. printplanets(solarsystem, SOLAR_PLANETS); 17. printf(" n n"); 18. return 0; 19. } 8-29
result of execution 8-30
구조체와포인터 구조체를가리키는포인터 포인터를멤버로가지는구조체 순서로살펴봅시다. 8-31
구조체를가리키는포인터 구조체를가리키는포인터 struct student *p; struct student s = { 20070001, " 홍길동 ", 4.3 p = &s; printf(" 학번 =%d 이름 =%s 학점 =%f \n", s.number, s.name, s.grade); printf(" 학번 =%d 이름 =%s 학점 =%f \n", (*p).number,(*p).name,(*p).grade); 8-32
-> 연산자 -> 연산자는구조체포인터로구조체멤버를참조할때사용 struct student *p; struct student s = { 20070001, " 홍길동 ", 180.2 p = &s; printf(" 학번 =%d 이름 =%s 키 =%f \n", s.number, s.name, s.grade); printf(" 학번 =%d 이름 =%s 키 =%f \n", (*p).number,(*p).name,(*p).grade); printf(" 학번 =%d 이름 =%s 키 =%f \n", p->number, p->name, p->grade); 8-33
-> 연산자 arrow operator (*p).number p 가가리키는구조체변수 == p->number p 가가리키는구조체변수의멤버 number p 가가리키는구조체변수의멤버 number 8-34
예제 // 포인터를통한구조체참조 #include <stdio.h> struct student { int number; char name[20]; double grade; 학번 =20070001 이름 = 홍길동학점 =4.300000 학번 =20070001 이름 = 홍길동학점 =4.300000 학번 =20070001 이름 = 홍길동학점 =4.300000 int main(void) { struct student s = { 20070001, " 홍길동 ", 4.3 struct student *p; p = &s; printf(" 학번 =%d 이름 =%s 키 =%f \n", s.number, s.name, s.grade); printf(" 학번 =%d 이름 =%s 키 =%f \n", (*p).number,(*p).name,(*p).grade); printf(" 학번 =%d 이름 =%s 키 =%f \n", p->number, p->name, p->grade); } return 0; 8-35
포인터를멤버로가지는구조체 struct date { int month; int day; int year; struct student { int number; char name[20]; double grade; struct date *dob; 8-36
포인터를멤버로가지는구조체 int main(void) { struct date d = { 3, 20, 1980 struct student s = { 20070001, "Kim", 4.3 학번 : 20070001 이름 : Kim 학점 : 4.300000 생년월일 : 1980 년 3 월 20 일 s.dob = &d; } printf(" 학번 : %d\n", s.number); printf(" 이름 : %s\n", s.name); printf(" 학점 : %f\n", s.grade); printf(" 생년월일 : %d년 %d월 %d일\n", s.dob->year, s.dob->month, s.dob->day ); return 0; 8-37
자기참조구조체 (Self-referential Structure) Self-referential structure( 자기참조구조체 ) a special structure that includes a pointer which points the same type structure // definition of data field typedef struct data { int id; char name[20]; char phone[12]; } DATA; // definition of node typedef struct NODE { DATA data; // data field struct NODE *link; // pointer to next node } NODE; 8-38
자기참조구조체의예 Binary Search Tree Node A node in a binary tree is like a node in a linked list, except it has two node pointer fields: typedef struct TreeNode { struct NodeData *pnodedata; // data field TreeNode *left; // link field TreeNode *right; // link field } TreeNode; A constructor can aid in the creation of nodes 8-39