Upload
kineta
View
62
Download
0
Embed Size (px)
DESCRIPTION
처음으로 배우는 C 프로그래밍. 제4부 복합 데이터 형 제 10 장 구조체. 구조체 소개. 구조체란 ? 하나의 이름으로 불려질 수 있는, 이질적인 자료형 변수들의 모임 예. 배열은 동일한 자료형을 가지는 변수들의 모임 Pascal 에서는 이를 레코드( record) 라고 부름 구조체는 복잡한 데이터를 간단히 처리할 수 있도록 지원 예 ) 책에 대한 정보를 관리하는 경우 구조체 책제목 (문자열 형) 저자 이름 (문자열 형) 출판사 ( 문자열 형 ) 책의 가격( 부동소수 형). 구조체 소개. - PowerPoint PPT Presentation
Citation preview
Ch 10. 구조체
처음으로 배우는 C 프로그래밍
제 4 부 복합 데이터 형
제 10 장 구조체
slide-slide-22Ch 10. 구조체
구조체 소개
구조체란 ?
하나의 이름으로 불려질 수 있는 , 이질적인 자료형 변수들의 모임 예 . 배열은 동일한 자료형을 가지는 변수들의 모임
Pascal 에서는 이를 레코드 (record) 라고 부름
구조체는 복잡한 데이터를 간단히 처리할 수 있도록 지원예 ) 책에 대한 정보를 관리하는 경우
구조체
책제목 ( 문자열 형 )
저자 이름 ( 문자열 형 )
출판사 ( 문자열 형 )
책의 가격 ( 부동소수 형 )
slide-slide-33Ch 10. 구조체
구조체 소개
구조체에 포함된 변수들을 그 구조체의 멤버 (member) 라고 부름각 멤버는 자신의 이름과 자료형을 가지며 , 개별적으로 참조 가능함
( 각 멤버는 변수나 배열의 원소와 동격임 )
C++ 에서는 구조체를 확장하여 클래스 (class) 를 생성함
구조체는 사용자 정의 타입으로 볼 수 있음
구조체의 형태 : 각 자료 항목의 기호명과 자료형의 배치로 구성책제목 ( 문자열 형 )저자이름 ( 문자열 형 )출판사 ( 문자열 형 )책의 가격 ( 부동소수 형 )
구조체의 내용 : 변수에 저장된 실 자료를 의미처음으로 배우는 C 프로그래밍영한 출판사유재수 , 서영훈18000
slide-slide-44Ch 10. 구조체
단일 구조체
구조체의 선언자료형 , 자료 명 , 자료 항목 배치를 작성구조체 정의 예제 : 년 - 월 - 일을 저장하는 구조체
struct {
int month; /* 월 */
int day; /* 일 */
int year; /* 년 */
} birth;
구조체 멤버 접근 방법 (.)
birth.month (birth 구조체 멤버 month 접근 )
birth.year (birth 구조체 멤버 year 접근 )
자료 항목 , 구조체 멤버
구조체 변수
slide-slide-55Ch 10. 구조체
#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.
단일 구조체
slide-slide-66Ch 10. 구조체
구조체 정의
변수 명을 갖는 구조체 정의단일 변수
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 */
slide-slide-77Ch 10. 구조체
구조체 정의 ( 계속 )
변수명이 없는 정의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)
slide-slide-88Ch 10. 구조체
#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};
구조체 정의 ( 계속 )
slide-slide-99Ch 10. 구조체
구조체 선언 예
회사원 정보 NameIdentification NumberRegular Pay RateOvertime Pay Rate
구조체 템플릿 선언 struct Pay_rec { char name[20]; int id_num; float reg_rate; float ot_rate;} ;
struct Pay_rec employee = {"H. Price", 12345, 1000.0, 50.0};
구조체 정의와 초기화
slide-slide-1010Ch 10. 구조체
사람의 이름과 생년월일을 위한 구조체Date 구조체를 이용하여 선언struct {
char name[20]; /* 이름을 저장하는 변수 */struct Date birth; /* 생년월일을 저장하는 변수 */
} person;
멤버 접근 방법person.name
person.birth.month
person.birth.day
person.birth.year
구조체 선언 예
slide-slide-1111Ch 10. 구조체
x y Name[0] … … … Name[9]
구조체 메모리 할당
x-y 좌표 상에서 “하나의 점과 그 이름을 표시하는 구조체”인 경우
struct aPoint {
int x;
int y;
char name[10];
} pt1;
pt1
slide-slide-1212Ch 10. 구조체
구조체 템플릿 정의와 변수선언
구조체 템플릿 정의와 구조체 변수 선언을 한 번에 할 수 있음
struct tag_name {
type1 member1;type2 member2; :typen membern;
} struct_variables, ... ;
예 )
struct aPoint {int x;int y;char name[5];
} pt1, pt2, pt3;
slide-slide-1313Ch 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 <= 열 번째 레코드
==================================================
slide-slide-1414Ch 10. 구조체
구조체 배열 ( 계속 )
사원을 위한 구조체struct Pay_rec {
long idnum;
char name[20];
float rate;
};
사원들의 정보를 저장하기 위한 구조체 배열struct Pay_rec empolyee[10];
구조체 배열의 접근employee[0].rate : 첫번째 사원의 급여 지급 비율
employee[4].idnum : 다섯번째 사원의 사원 번호
slide-slide-1515Ch 10. 구조체
구조체 배열 ( 계속 )
#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.7233623 Bohm, P. 7.5434145 Donaldson, S. 5.5635987 Ernst, T. 5.4336203 Gwodz, K. 8.72
출력결과
slide-slide-1616Ch 10. 구조체
구조체 포인터
구조체 타입의 포인터 변수예 ) struct aPoint *pt1, *pt2, *pt3;
포인터 변수로부터 구조체의 멤버를 참조하는 방법포인터의 성질을 이용한 방법 : (*pt1).x
‘->’ 연산자를 이용한 방식 : pt1 -> x
‘->’ 연산 ‘->’ 연산자의 왼쪽은 구조체의 주소 , 오른쪽은 그의 멤버이름을 넣어야 함
구조체 연산자와 -> 는 함수의 ( ) 와 배열 첨자의 [ ] 와 함께 연산 순위가 가장 높음
*point.x 는 *(point.x) 와 같은 효과를 지니고++pt->x 는 ++(pt->x) 와 같은 효과를 지닌다 .
slide-slide-1717Ch 10. 구조체
구조체 전달
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);
slide-slide-1818Ch 10. 구조체
#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
구조체 전달
slide-slide-1919Ch 10. 구조체
구조체 전달 ( 계속 )
구조체 전달 ( 주소에 의한 )
호출문
calc_net(&emp);
피호출문 void calc_net(struct Employee *pt) { /*pt: 구조체 포인터 변수 */
}
emp의시작주소
pt:(*pt).hours
(*pt).pay_rate
(*)pt.id_ num = *pt
id_ num pay_rate hours
emp :
slide-slide-2020Ch 10. 구조체
#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);}
구조체 전달 ( 계속 )
slide-slide-2121Ch 10. 구조체
구조체 반환
함수의 반환 값으로 구조체를 받기를 원하는 경우 스칼라 (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
slide-slide-2222Ch 10. 구조체
#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);}
출력결과 The employee id number is 6789 The employee pay rate is $16.25 The employee hours are 38.00
구조체 반환
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);}
slide-slide-2323Ch 10. 구조체
동적 메모리 할당
프로그램에서 정의된 모든 변수는 그 변수의 값을 저장하기에 충분한 기억장소를 컴퓨터 메모리로부터 할당 받음 특정 메모리 위치가 변수를 위해 확보되면 , 변수의 유효 범위 (life time) 내에서는 그 위치가 사용되든 그렇지 않든 그 위치는 변하지 않는다
예 : 500 개의 정수를 저장하는 배열 사용하는 정수 : 10 개 , 490 개의 기억 공간 낭비
=> 효율적인 기억 장소 필요성 필요할 때 필요한 만큼 기억장소를 확보 불필요한 기억장소는 해제
slide-slide-2424Ch 10. 구조체
동적 메모리 할당 함수
동적 메모리 할당을 위한 include 함수명 : stdlib.h
메모리 할당 함수 - 함수명 : malloc(int ) - 기능 : 요구된 바이트 수 () 만큼 기억장소를 확보한다 . 성공적으로 기억장소를 확보하면 기억장소의 시작 주소를 반환하고 충분한 메모리가 없는 경우 NULL 을 반환한다 . - 예 : int *pt; pt = malloc(200 * sizeof(int));
메모리 해제 함수 - 함수명 : free() - 기능 : 미리 확보된 바이트의 블록을 해제한다 . 해제될 기억장소의 시작 주소가 이 함수의 인자로 사용된다 . - 예 : free(pt);
slide-slide-2525Ch 10. 구조체
int numgrades; int *grades; /* 정수형 포인터 변수 정의 */ printf("Enter the number of grades to be processed: "); scanf("%d", &numgrades); /* 요구된 만큼의 정수형 배열을 위한 기억장소 할당 */ grades = (int *) malloc(numgrades * sizeof(int));
배열의 크기를 입력 받아 그 만큼의 배열을 위한 기억 장소 할당
동적 메모리 할당 함수
slide-slide-2626Ch 10. 구조체
#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); }
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); }
동적 메모리 할당 함수
slide-slide-2727Ch 10. 구조체
구조체 동적 기억장소 할당
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)}
slide-slide-2828Ch 10. 구조체
공용체 (Union)
공용체는 사용할 때마다 이질적인 멤버의 자료형과 다른 크기를 가질 수 있도록 하는 구조체임
비교 ) 파스칼의 가변 레코드와 동일함 하나의 메모리 장소에 여러 데이터 형의 자료를 저장 가능하도록 지원
즉 , 여러 자료형의 변수가 하나의 주소를 공유하게 함 여러 값이 동시에 저장될 수는 없음 . 즉 , 한 시점에 하나의 자료만 저장됨 공용체의 선언은 구조체와 동일함
union u_tag {int ival;float fval;char *sval;
} u, *uptr, uarray[10];
공용체 u_tag 의 크기는 int, float, char 중에서 가장 큰 것으로 할당됨 비교 ) 구조체의 크기는 모든 멤버들의 크기의 합과 같음
slide-slide-2929Ch 10. 구조체
공용체 ( 계속 )
구조체에서 정의된 . 과 -> 연산자도 공용체에서 동일한 의미로 사용
u.fvaluptr->ival
공용체 u 에는 세 가지 자료형 (int, float, char) 중 어느 것으로도 할당 가능 그러나 , 할당된 값의 참조는 가장 최근에 할당한 자료형으로만 가능함 ( 이는 전적으로 프로그래머 책임임 )
slide-slide-3030Ch 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 사용 */
union u_tag {int ival;float fval;char *sval;
} u, *uptr, uarray[10];
공용체 ( 계속 )
slide-slide-3131Ch 10. 구조체
공용체 ( 계속 )
구조체 안에 공용체을 , 반대로 공용체 안에 구조체를 선언할 수도 있음 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);