1 / 31

처음으로 배우는 C 프로그래밍

처음으로 배우는 C 프로그래밍. 제4부 복합 데이터 형 제 10 장 구조체. 구조체 소개. 구조체란 ? 하나의 이름으로 불려질 수 있는, 이질적인 자료형 변수들의 모임 예. 배열은 동일한 자료형을 가지는 변수들의 모임 Pascal 에서는 이를 레코드( record) 라고 부름 구조체는 복잡한 데이터를 간단히 처리할 수 있도록 지원 예 ) 책에 대한 정보를 관리하는 경우 구조체 책제목 (문자열 형) 저자 이름 (문자열 형) 출판사 ( 문자열 형 ) 책의 가격( 부동소수 형). 구조체 소개.

kineta
Télécharger la présentation

처음으로 배우는 C 프로그래밍

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 처음으로 배우는 C 프로그래밍 제4부 복합 데이터 형 제 10 장 구조체

  2. 구조체 소개 • 구조체란 ? • 하나의 이름으로 불려질 수 있는, 이질적인 자료형 변수들의 모임 • 예. 배열은 동일한 자료형을 가지는 변수들의 모임 • Pascal에서는 이를 레코드(record)라고 부름 • 구조체는 복잡한 데이터를 간단히 처리할 수 있도록 지원 • 예 ) 책에 대한 정보를 관리하는 경우 • 구조체 책제목 (문자열 형) 저자 이름 (문자열 형) 출판사 ( 문자열 형 ) 책의 가격( 부동소수 형)

  3. 구조체 소개 • 구조체에 포함된 변수들을 그 구조체의 멤버(member)라고 부름 • 각 멤버는 자신의 이름과 자료형을 가지며, 개별적으로 참조 가능함 • (각 멤버는 변수나 배열의 원소와 동격임) • C++ 에서는 구조체를 확장하여 클래스(class)를 생성함 • 구조체는 사용자 정의 타입으로 볼 수 있음 • 구조체의 형태: 각 자료 항목의 기호명과 자료형의 배치로 구성 책제목(문자열 형) 저자이름(문자열 형 ) 출판사(문자열 형) 책의 가격( 부동소수 형) • 구조체의 내용: 변수에 저장된 실 자료를 의미 처음으로 배우는 C프로그래밍 영한 출판사 유재수, 서영훈 18000

  4. 단일 구조체 • 구조체의 선언 • 자료형, 자료 명, 자료 항목 배치를 작성 • 구조체 정의 예제: 년-월-일을 저장하는 구조체 struct { int month; /* 월 */ int day; /* 일*/ int year; /* 년*/ } birth; • 구조체 멤버 접근 방법 (.) • birth.month (birth 구조체 멤버 month 접근) • birth.year (birth 구조체 멤버 year 접근) 자료 항목, 구조체 멤버 구조체 변수

  5. 단일 구조체 #include <stdio.h> void main(void) { struct { int month; int day; int year; } birth; birth.month = 6; birth.day = 11; birth.year = 1999; printf("My birth date is %d/%d/%d.", birth.month, birth.day, birth.year); } 출력 결과 My birth date is 6/11/1999.

  6. 구조체 정의 • 변수 명을 갖는 구조체 정의 • 단일 변수 struct { int month; int day; int year; } birth; • 여러 변수 struct { int month; int day; int year; } birth, current; /* birth.month, birth.day, birth.year */ /* current.month, current.day, current.year */

  7. 구조체 정의 (계속) • 변수명이 없는 정의 struct Date { /* Date : 구조체 태그(tag) 명, 구조체 이름 */ int month; int day; int year; }; • 구조체 템플릿을 이용한 변수 선언 • struct Date birth, current; • 멤버 접근 • birth.month, birth.day, birth.year • current.month, current.day, current.year 구조체 템플릿(template)

  8. 구조체 정의 (계속) #include <stdio.h> struct Date { int month; int day; int year; }; void main(void) { struct Date birth; birth.month = 6; birth.day = 11; birth.year = 1999; printf("My birth date is %d/%d/%d", birth.month, birth.day, birth.year); } 구조체 템플릿 Date선언 또는 struct Date birth = {6, 11, 1999}; 구조체 멤버의 초기화

  9. 구조체 선언 예 구조체 템플릿 선언 struct Pay_rec { char name[20]; int id_num; float reg_rate; float ot_rate; } ; 회사원 정보 Name Identification Number Regular Pay Rate Overtime Pay Rate 구조체 정의와 초기화 struct Pay_rec employee = {"H. Price", 12345, 1000.0, 50.0};

  10. 구조체 선언 예 • 사람의 이름과 생년월일을 위한 구조체 • Date 구조체를 이용하여 선언 struct { char name[20]; /* 이름을 저장하는 변수 */ struct Date birth; /* 생년월일을 저장하는 변수 */ } person; • 멤버 접근 방법 • person.name • person.birth.month • person.birth.day • person.birth.year

  11. 구조체 메모리 할당 • x-y 좌표 상에서 “하나의 점과 그 이름을 표시하는 구조체”인 경우 struct aPoint { int x; int y; char name[10]; } pt1; … … … x y pt1 Name[0] Name[9]

  12. 구조체 템플릿 정의와 변수선언 • 구조체 템플릿 정의와 구조체 변수 선언을 한 번에 할 수 있음 struct tag_name { type1 member1; type2 member2; : typen membern; } struct_variables, ... ; 예) struct aPoint { int x; int y; char name[5]; } pt1, pt2, pt3;

  13. 구조체 배열 • 사원에 대한 자료 사원번호 사원이름 사원급여지급비율 ================================================= 32479 Abrams, B. 6.72 <= 첫 번째 레코드 33623 Bohm, P. 7.54 <= 두 번째 레코드 34145 Donaldson, S. 5.56 <= 세 번째 레코드 35987 Ernst, T. 5.43 <= 네 번째 레코드 36203 Gwodz, K. 8.72 <= 다섯 번째 레코드 36417 Hanson, H. 7.64 <= 여섯 번째 레코드 37634 Monroe, G. 5.29 <= 일곱 번째 레코드 38321 Price, S. 9.67 <= 여덟 번째 레코드 39435 Robbins, L. 8.50 <= 아홉 번째 레코드 39567 Willians, B. 7.20 <= 열 번째 레코드 ================================================== 정수형 배열 문자형 배열 실수형

  14. 구조체 배열 (계속) • 사원을 위한 구조체 struct Pay_rec { long idnum; char name[20]; float rate; }; • 사원들의 정보를 저장하기 위한 구조체 배열 • struct Pay_rec empolyee[10]; • 구조체 배열의 접근 • employee[0].rate : 첫번째 사원의 급여 지급 비율 • employee[4].idnum : 다섯번째 사원의 사원 번호

  15. 구조체 배열 (계속) #include <stdio.h> struct Pay_rec { long id; char name[20]; float rate; }; void main(void) { int i; struct Pay_rec employee[10] = { 32479, "Abrams, B.", 6.72, 33623, "Bohm, P.", 7.54, 34145, "Donaldson, S.", 5.56, 35987, "Ernst, T.", 5.43, 36203, "Gwodz, K.", 8.72, 36417, "Hanson, H.", 7.64, 37634, "Monroe, G.", 5.29, 38321, "Price, S.", 9.67, 39435, "Robbins, L.", 8.50, 39567, "Willians, B.", 7.20 }; for (i=0; i<5; i++) printf(“\n%ld %-20s %4.2f", employee[i].id, employee[i].name, employee[i].rate); } 출력결과 32479 Abrams, B. 6.72 33623 Bohm, P. 7.54 34145 Donaldson, S. 5.56 35987 Ernst, T. 5.43 36203 Gwodz, K. 8.72

  16. 구조체 포인터 • 구조체 타입의 포인터 변수 예) struct aPoint *pt1, *pt2, *pt3; • 포인터 변수로부터 구조체의 멤버를 참조하는 방법 • 포인터의 성질을 이용한 방법 : (*pt1).x • ‘->’연산자를 이용한 방식 : pt1 -> x • ‘->’연산 • ‘->’연산자의 왼쪽은 구조체의 주소, 오른쪽은 그의 멤버이름을 넣어야 함 • 구조체 연산자와 -> 는 함수의 ( )와 배열 첨자의 [ ]와 함께 연산 순위가 가장 높음 • *point.x는 *(point.x)와 같은 효과를 지니고 • ++pt->x는 ++(pt->x)와 같은 효과를 지닌다.

  17. 구조체 전달 struct { int id_num; double pay_rate; double hours; } emp; • 스칼라(scalar) 변수와 같은 방법으로 전달 • display(emp.id_num); • calc_pay(emp.pay_rate, emp.hours); • 구조체 전달(값에 의해) • calc_net(emp);

  18. 구조체 전달 #include <stdio.h> struct Employee { int id_num; double pay_rate; double hours; }; void main(void) { struct Employee emp = {6782, 8.93, 40.5}; double net_pay; double calc_net(struct Employee); net_pay = calc_net(emp); printf("The net pay for employee %d is $%6.2f", emp.id_num, net_pay); } double calc_net(struct Employee temp) { return (temp.pay_rate * temp.hours); } 출력결과 The net pay for employee 6782 is $361.66

  19. 구조체 전달 (계속) 구조체 전달(주소에 의한) 피호출문 void calc_net(struct Employee *pt) { /*pt: 구조체 포인터 변수 */ } 호출문 calc_net(&emp);

  20. 구조체 전달 (계속) #include <stdio.h> struct Employee { int id_num; double pay_rate; double hours; }; void main(void) { struct Employee emp = {6782, 8.93, 40.5}; double net_pay; double calc_net(struct Employee *); net_pay = calc_net(&emp); printf("The net pay for employee %d is $%6.2f", emp.id_num, net_pay); } double calc_net(struct Employee *temp) { return (temp->pay_rate * temp->hours); }

  21. 구조체 반환 • 함수의 반환 값으로 구조체를 받기를 원하는 경우 스칼라(scalar) 값을 반환할 때와 같은 방법으로 구조체를 반환 #include <stdio.h> struct Employee { int id_num; double pay_rate; double hours; }; struct Employee get_vals(void) { struct Employee em; …. return em; } 구조체반환 void main() { struct Employee emp; ... emp = get_vals(); /*함수 호출*/ } emp.id_num = em.id_num; emp.pay_rate = em.pay_rate; emp.hours = em.hours

  22. 구조체 반환 #include <stdio.h> struct Employee { int id_num; double pay_rate; double hours; }; void main(void) { struct Employee emp; struct Employee get_vals(void); emp = get_vals(); printf("\f2 nThe employee id number is %d", emp.id_num); printf("The employee pay rate is $%5.2f", emp.pay_rate); printf("The employee hours are %5.2f", emp.hours); } struct Employee get_vals(void) { struct Employee new_emp; new_emp.id_num = 6789; new_emp.pay_rate = 16.25; new_emp.hours = 38.0; return (new_emp); } 출력결과 The employee id number is 6789 The employee pay rate is $16.25 The employee hours are 38.00

  23. 동적 메모리 할당 • 프로그램에서 정의된 모든 변수는 그 변수의 값을 저장하기에 충분한 기억장소를 컴퓨터 메모리로부터 할당 받음 • 특정 메모리 위치가 변수를 위해 확보되면, 변수의 유효 범위(life time)내에서는 그 위치가 사용되든 그렇지 않든 그 위치는 변하지 않는다 • 예: 500 개의 정수를 저장하는 배열 사용하는 정수: 10개, 490개의 기억 공간 낭비 => 효율적인 기억 장소 필요성 • 필요할 때 필요한 만큼 기억장소를 확보 • 불필요한 기억장소는 해제

  24. 동적 메모리 할당 함수 동적 메모리 할당을 위한 include 함수명: stdlib.h 메모리 할당 함수 - 함수명: malloc(int ) - 기능: 요구된 바이트 수() 만큼 기억장소를 확보한다. 성공적으로 기억장소를 확보하면 기억장소의 시작 주소를 반환하고 충분한 메모리가 없는 경우 NULL을 반환한다. -예: int *pt; pt = malloc(200 * sizeof(int)); 메모리 해제 함수 -함수명: free() -기능: 미리 확보된 바이트의 블록을 해제한다. 해제될 기억장소의 시작 주소가 이 함수의 인자로 사용된다. -예: free(pt);

  25. 동적 메모리 할당 함수 배열의 크기를 입력 받아 그 만큼의 배열을 위한 기억 장소 할당 int numgrades; int *grades; /* 정수형 포인터 변수 정의 */ printf("Enter the number of grades to be processed: "); scanf("%d", &numgrades); /* 요구된 만큼의 정수형 배열을 위한 기억장소 할당 */ grades = (int *) malloc(numgrades * sizeof(int));

  26. 동적 메모리 할당 함수 for (i=0; i < numgrades; i++) { printf(" Enter a grade: "); scanf("%d", &grades[i]); } printf("\f2 nAn array was created for %d integers", numgrades); printf("\f2 nThe vales stored in the array are:"); for (i=0; i < numgrades; i++) printf(" %d", grades[i]); free(grades); } #include <stdio.h> #include <stdlib.h> void main(void) { int numgrades; int *grades; /* 정수형 포인터 변수 정의 */ printf("Enter the number of grades to be processed: "); scanf("%d", &numgrades); /* 요구된 만큼의 정수형 배열을 위한 기억장 소 할당 */ grades = (int *) malloc(numgrades * sizeof(int)); /* 동적기억장소할당이 정상적으로 이루어졌는지를 검사 */ if (grades == (int *) NULL) { printf("Failed to allocate grades array "); exit(1); }

  27. 구조체 동적 기억장소 할당 struct Office_info { 자료 멤버들; }; struct Office_info *off; /*할당된 주소를 저장하기 위한 포인터 변수 */ /* 구조체를 저장하기 위한 공간 확보 */ off = (struct Office_info *) malloc(sizeof(struct Office_info)); /* 공간이 할당되었는지를 점검 */ if (off == (struct Office_info *) NULL) { printf("\f2 nAllocation of Office info record failed"); exit(1) }

  28. 공용체(Union) • 공용체는 사용할 때마다 이질적인 멤버의 자료형과 다른 크기를 가질 수 있도록 하는 구조체임 비교) 파스칼의 가변 레코드와 동일함 • 하나의 메모리 장소에 여러 데이터 형의 자료를 저장 가능하도록 지원 즉, 여러 자료형의 변수가 하나의 주소를 공유하게 함 • 여러 값이 동시에 저장될 수는 없음. 즉, 한 시점에 하나의 자료만 저장됨 • 공용체의 선언은 구조체와 동일함 union u_tag { int ival; float fval; char *sval; } u, *uptr, uarray[10]; • 공용체 u_tag의 크기는 int, float, char 중에서 가장 큰 것으로 할당됨 비교) 구조체의 크기는 모든 멤버들의 크기의 합과 같음

  29. 공용체 (계속) • 구조체에서 정의된 . 과 -> 연산자도 공용체에서 동일한 의미로 사용 u.fval uptr->ival • 공용체 u에는 세 가지 자료형 (int, float, char) 중 어느 것으로도 할당 가능 • 그러나, 할당된 값의 참조는 가장 최근에 할당한 자료형으로만 가능함 (이는 전적으로 프로그래머 책임임 )

  30. 공용체 (계속) • union u_tag { • int ival; • float fval; • char *sval; • } u, *uptr, uarray[10]; u.fval = 2.0; /* 10이 지워지고 2.0이 저장; 4byte사용 */ u.sval = “I am a boy,”; /* 2.0이 지워지고 주소가 저장; 4byte사용 */ uptr = &u; x = uptr -> fval; /* Error!! 가장 최근에 문자 포인터로 사용했기 때문에 */ u.ival = 10; /* 10이 저장; 2byte사용 */

  31. 공용체 (계속) • 구조체 안에 공용체을, 반대로 공용체 안에 구조체를 선언할 수도 있음 struct { char *name; int flags; int utype; union { int ival; float fval; char *sval; } u; } symtab[NSYM]; if ( symtab[n].utype == INT) printf(“%d\n”, symtab[n].u.ival); else if (symtab[n].utype == FLOAT) printf(“%f\n”, symtab[n].u.fval); else if (symtab[n].utype == STRING) printf(“%s\n”, symtab[n].u.sval);

More Related