420 likes | 580 Views
멘토링 7 주차. 11.08.23. 동적 메모리 할당. 정적 할당 (Static Allocation) 변수선언에 의하여 변수의 타입에 맞는 크기만큼 메모리를 할당 동적 할당 (Dynamic Allocation) 포인터 변수를 사용하여 실행 중에 기억장소를 할당. int a; // int 타입 크기 만큼의 공간을 할당 (4 바이트 ) char c; //char 타입 크기 만큼의 공간 할당 (1 바이트 )
E N D
멘토링7주차 11.08.23
동적 메모리 할당 • 정적 할당 (Static Allocation) • 변수선언에 의하여 변수의 타입에 맞는 크기만큼 메모리를 할당 • 동적 할당 (Dynamic Allocation) • 포인터 변수를 사용하여 실행 중에 기억장소를 할당 int a; //int타입 크기 만큼의 공간을 할당 (4바이트) char c; //char 타입 크기 만큼의 공간 할당(1바이트) float f[10]; //float타입 크기 만큼의 공간을 10개 할당 (4바이트 * 10) int *p; //포인터 변수 선언 p = (int *) malloc(4); //4바이트의 메모리 공간을 할당하여 시작주소를 반환하여 p에 대입 free(p); //p에 할당된 메모리 공간을 해제 dynamic allocation
메모리 관리 함수 • 메모리할당과해제에관련된함수(<stdlib.h>) dynamic allocation
malloc() • 함수원형 void * malloc(size_t) • 지정한 바이트 수 만큼 힙 영역의 메모리 공간을 할당하여 주소를 반환하는 함수 • 변수타입의 크기, 배열의 크기에 따른 바이트 수를 계산하여 매개변수로 사용 • 할당된 공간은 초기화 되지 않는다 • 메모리 공간이 부족한 경우엔 NULL값 반환 • 사용 예 (1)하나의 값을 저장할 공간 확보 int *ip; ip = (int *) malloc(sizeof(int)); //저장할 값의 자료 형 크기로 메모리할당 if (ip != NULL) *ip = 100; 100 int형의 크기 (4바이트) ip dynamic allocation
(2)배열 공간 확보 int *ap; ap = (int *) malloc(sizeof(int) * 5); //int형의 크기 만큼 5개 공간 확보 *ap = 1; //ap[0] *(ap+1) = 2; //ap[1] *(ap+4) = 9; //ap[4] 1 2 … 9 int형의 크기 (4바이트) * 5 ap ap[0] ap[1] … ap[4] (3)문자열 공간 확보 char *str; str = (char *) malloc(100); //길이 99인 문자열 저장 공간 확보 gets(str); … char형의 크기 (1바이트) * 100 str dynamic allocation
p[0] p[1] p[2] p[1][0] p[2][0] p[0][0] p[2][1] p[0][1] p[1][1] p[2][2] p[1][2] p[0][2] p[0][3] p[1][3] p[2][3] 2차원 배열 동적 할당 p dynamic allocation
연습문제 1)ID 리스트를 동적으로 구성하여 검색하는 프로그램 작성 <처리조건> -ID list의 인원수를 입력하여 동적으로 배열의 공간을 할당 -ID list에 인원수(n)만큼 id를 추가하는 함수 구현 void input(char **idlist, int n) -유효성 검사 함수 구현 :ID를 매개변수로 넘겨서 길이(8자리)와 영숫자로 구성되었는가를 확인 char * chkID(char *); 반환값: 유효한 경우 - NULL 길이가 범위 내의 값이 아니면 “길이오류” 영 숫자가 아니면 “형식오류” -ID list에서 특정 ID를 검색하는 함수 구현 :검색할 id를 반복 입력하여 회원인지 아닌지를 확인하는 함수 void search(char **idlist, int n) <출력예시> *회원 수 입력 : 3 >>ID입력 : a123 >>ID입력 : b333 >>ID입력 : c123456789 =>길이오류 >>ID입력 : d!@# =>형식오류 >>ID입력 : e999 *회원 목록* a123 b333 e999 >>검색할 ID입력 (종료:q) a123 입력한 ID는 회원입니다 >>검색할 ID입력 (종료:q) sdsd 입력한 ID는 회원이 아닙니다 >>검색할 ID입력 (종료:q) q dynamic allocation
구조체(Struct) • 여러 형태의 자료를 하나의 자료 형으로 통합하여 관리하는 구조 • 예 : 성적처리를 위한 데이터 구조 /* (2) 구조체 선언 형태 */ struct grade{ // 구조체 이름(Tag) char name[30]; int kor; int eng; int math; int sum; float avg; }; struct grade sc; //구조체 변수 선언 /* (1)일반 자료형 선언 형태 */ char name[30]; //성명 int kor; // 국어 int eng; // 영어 int math; // 수학 int sum; // 총점 float avg; // 평균 구조체 구성요소 (member) struct
구조체 정의 • 구조체 멤버를 이용하여 새로운 구조체 자료형을 정의하는 구문 • 구조체 멤버 • 구조체를 구성하는 데이타들(구성요소, member) • 구조체 정의 구문에서는 각 구성요소의 초기값을 대입할 수 없음 • 한 구조체 내부에서 선언되는 구조체 멤버의 이름은 모두 유일 struct
구조체 변수 선언 • 정의된 구조체 이름의 자료형으로 구조체 변수 선언 struct
다양한 구조체 변수 선언 형태 //구조체 정의(구조체명 포함)에서 변수선언 structgrade{ char name[30]; int kor; int eng; int mat; float avg; }st1; //구조체 정의 structgrade{ char name[30]; int kor; int eng; int mat; float avg; }; //변수선언 struct grade st1; //구조체정의에서 변수선언 struct { char name[30]; int kor; int eng; int mat; float avg; }st1; st1 struct
사용자 정의 데이터 형 (typedef ) • 데이터형의 이름을 새롭게 정의하기 위한 명령 • 형식 typedef 데이터 형 새 이름 • 예제 • typedef char * STRING; // 문자열을 STRING형으로 정의 • typedef unsigned char BYTE; • typedef struct{ // 구조체를 복소수(COMPLEX)형으로 정의 • float r; // 실수부 • float i; // 허수부 • }COMPLEX; • STRING str; // 변수 str을 문자열 형으로 선언 • BYTE i; // 변수 i를 BYTE 형으로 선언 • COMPLEX num; // 변수 num을 복소수로 선언 struct
typedef를 이용한 구조체 정의 • 구조체 정의 후 변수 선언에 사용될 자료 형을 간단하게 표현하기 위한 자료 형 정의 • 방법 • typedef로 구조체 정의 • 정의된 구조체를 더 간단하게 선언 struct book { char title[50]; //제목 char author[50]; //저자 char publish[50]; //출판사 int pages; //페이지수 int price; //가격 }; typedef struct book book ; … book yourbook; book mybook; struct
k i m m i n h o \0 ••• 100 100 0 구조체 변수의 초기화 • 구조체 변수 선언 시 중괄호({})를 이용하여 구조체 구성요소의 자료형에 맞추어 초기값 지정 • 구성요소의 정의된 순서에 맞추어 초기값이 저장 • 구성요소의 개수보다 적을 경우 남은 부분은 0로 초기화 • 예 struct grade{ char name[30]; int kor; int eng; float avg; }; main (){ struct grade st1={“kim min ho”, 100, 100}; ... } name[30] kor eng avg struct
구조체 구성요소(member) 참조 • 구조체를 구성하는 구성요소를 표현하기 위해 멤버연산자(.)를 이용 <형식> 구조체변수.구성요소 <예> 구조체변수.구성요소 = 값; 변수 = 구조체변수.구성요소 struct
연습문제(1) • 회원정보를 구조체로 구성하여 회원가입프로그램을 작성 <처리조건> • 회원 정보 : id(9), pwd(9), age • 반복 입력, id에 “quit”가 입력되면 종료 • 나이가 20세 미만이면 “20세 이상만 회원가입이 가능합니다.” 메시지 출력 • 나이가 20세 이상이면 가입 축하 인사와 회원 정보 출력 <출력예시> >>ID(종료-quit): hong >>Password : h1234 >>age : 10 **20세이상만 회원가입이 가능합니다. >>ID(종료-quit): kim >>Password : k4040 >>age : 30 **회원가입을 축하합니다. [ID:kim Password:k4040 age:30] >>ID(종료-quit): quit **프로그램을 종료합니다. struct
st1[0].name st1[0].ko r st1[0].eng st1[0].math st1[0].sum st1[0].avg st1[1].name st1[1].kor st1[1].eng st1[1].math st1[1].sum st1[1].avg st1[9].name st1[9].kor st1[9].eng st1[9].math st1[9].sum st1[9].avg … 구조체 배열 • 같은 구조체를 가지는 여러 자료를 관리하기 위한 구조 • 형식 struct 구조체이름 배열명[크기]; • 예 struct grade st1[10]; • 배열구조 name kor eng math sum avg st1[0] st1[1] ... st1[9] struct
구조체 배열 예제 struct
구조체 배열 초기화 //도서정보 구조체 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} }; struct
구조체 포인터 • 구조체 변수의 주소를 가지는 포인터 형 예)struct grade *stp, *stp2, st1, st2[10]; stp = &st1; stp2 = st2; • 구조체 포인터의 구성요소 참조 1) 포인터의 참조연산자(*) 이용 (*stp).kor = 100; (*stp).eng = 90; (*stp).math = 97; (*stp).sum = (*stp).kor + (*stp).eng + (*stp).math; 2)구조체 포인터 참조 연산자 ('->' )이용 구조체포인터->멤버변수 = 값; 변수 = 구조체포인터->멤버변수; stp->kor = 100; stp->eng = 90; stp->math = 97; stp->sum = stp->kor + stp->eng + stp->math; struct
구조체 포인터 예제 struct
구조체와 함수 • 구조체의 구성요소를 함수의 매개변수로 이용 2. 구조체를 매개변수로 이용 • /* 함수호출 */ • st1.sum = sum_fun(st1.kor,st1.eng,st1.math); • /* 함수정의 */ • int sum_fun(int a, int b, int c){ • return(a + b + c); • } • /* 함수호출 */ • st1.sum = sum_fun(st1); • /* 함수정의 */ • int sum_fun(struct grade st){ • return(st.kor + st.eng + st.math); • } struct
3. 구조체 주소를 매개변수로 이용 • /* 함수호출 */ • sum_fun(&st1); • /* 함수정의 */ • sum_fun(struct grade *st){ • st->sum = st->kor + st->eng + st->math; • } struct
4. 구조체 배열을 함수에 이용 //structFunction.c, 구조체 배열을 매개변수로 하는 함수사용 예 (성적처리) #include <stdio.h> #define MAXST 10 struct grade{ char name[30]; int kor; int eng; int math; int sum; float avg; }; void get_data(struct grade *st, int n); void make_data(struct grade *st, int n); void put_data(const struct grade *st, int n); main (){ int i; struct grade st1[MAXST]; int num; printf(">>입력할 학생의 수는? "); scanf("%d", &num); get_data(st1, num); // 데이터를 입력하는 함수 호출 make_data(st1,num); // 총점, 평균을 계산하는 함수 호출 put_data(st1, num); // 데이터를 출력하는 함수 호출 } struct
//structFunction.c 계속 //구조체 배열에 각 점수를 입력 받는 함수 void get_data(struct grade *st, int n){ //구조체 배열을 포인터로 받아서 처리 int i; printf("%d명의 성명, 국어, 영어, 수학 점수 입력 \n", n); for ( i = 0; i < n; i++, st++){ printf("%d : ", i + 1); scanf("%s %d %d %d", st->name, &st->kor, &st->eng, &st->math); //각 점수를 입력 } } //구조체 배열의 총점과 평균 계산 함수 void make_data(struct grade *st, int n){ int i; for ( i = 0; i < n; i++, st++){ st->sum = st->kor + st->eng + st->math; //총점계산 st->avg = (float) st->sum / 3; //평균계산 } } //구조체 배열 출력 함수 void put_data(const struct grade *st, int n){ int i; for ( i = 0; i < n; i++, st++) printf("name =%s, sum=%d, average= %.2f\n", st->name, st->sum, st->avg); //출력 } struct
연습문제(2) • 구조체 배열을 이용한 성적처리 수정 (1)grade 구조체에 학점(grd) , 등수(rank) 데이터 추가 (2)make_data 함수에서 학점 구하는 함수 호출 char grd_make(float avg) :평균을 받아서 학점을 return 90이상 100이하 : A, 80이상 90미만 : B, 70이상 80미만 : C, 60이상 70미만 : D, 60미만 : F (3) 등수 구하는 함수 작성 rank_make(struct grade *st, int n) struct
구조체 배열과 동적 할당 //structMalloc.c, 구조체 배열의 동적 할당을 사용한 성적처리 예 #include<stdio.h> #include<stdlib.h> typedef struct{ int num; int kor; int eng; int mat; float avg; } sctype; //구조체 타입 정의 main() { sctype *sc, *scp; // 구조체 포인터 변수 선언 int i, n; printf("학생 수 입력="); scanf("%d", &n); sc = (sctype *) calloc(n, sizeof(sctype)); // 구조체 크기를 학생수(n)만큼 확보 scp = sc; //확보된 메모리의 주소를 대입 for (i=0; i < n; i++, scp++){ //포인터를 증가시키면서 구조체에 데이터 입력 scp->num = i + 1; printf("%d번 입력\n", scp->num); printf("국어:"); scanf("%d", &scp->kor); printf("영어:"); scanf("%d", &scp->eng); printf("수학:"); scanf("%d", &scp->mat); scp->avg = (scp->kor + scp->eng + scp->mat) / 3.0; } printf("번호 국어 영어 수학 평균\n"); for (i=0; i < n; i++, sc++) printf("%4d %3d %3d %3d %5.2f\n", sc->num, sc->kor, sc->eng, sc->mat, sc->avg); } struct
num kind author bcard book bname abstract 중첩 구조체 • 하나의 구조체 안에 또 다른 구조체를 포함하고 있는 구조 • 도서관리 예제 typedef struct{ char kind[10]; //분류 char bname[20]; //서명 char author[10]; //저자 char abstract[30]; //요약 } ctype; //도서정보 구조체 typedef struct{ char num[4]; //도서번호 ctype book; //도서정보 구조체 }btype; //도서카드 구조체 btype bcard; //도서카드 변수 선언 struct
중첩구조체 구성요소 접근 main(){ btype bcard; printf("book input : \n"); printf("도서번호 : "); gets(bcard.num); printf(“분 류 : "); gets(bcard.book.kind); //구조체 구성요소접근 연산자(.)이용 printf("도 서 명 : "); gets(bcard.book.bname); printf("저 자 : "); gets(bcard.book.author); printf("요 약 : "); gets(bcard.book.abstract); printf("=============================\n"); printf("도서번호 : "); puts(bcard.num); printf(“분 류 : "); puts(bcard.book.kind); printf("도 서 명 : "); puts(bcard.book.bname); printf("저 자 : "); puts(bcard.book.author); printf("요 약 : "); puts(bcard.book.abstract); printf("=============================\n"); } struct
중첩 구조체 동적할당 • 여러 개의 데이타를 관리할 때 입력 데이타가 있을 경우만 공간을 확보하여 메모리 공간 절약 • 도서관리를 위한 도서리스트에서 도서정보가 있을 경우만 동적 할당 num book 종류 도서명 저자 요약 blist 0 1 … Max struct
//도서관리 프로그램 (book.c) #include <stdio.h> #include <string.h> #include <stdlib.h> #define MAXSIZE 10 typedef struct{ char kind[10]; char bname[20]; char author[10]; char abstract[30]; } ctype; typedef struct{ char num[4]; ctype *book; //구조체 포인터 }btype; void input_rtn(btype *blist); //도서정보 입력 함수 void output_rtn(btype *blist, int idx); //도서정보 출력함수 main(){ btype blist[MAXSIZE]; char in_num[4]; int idx=0; while(idx < MAXSIZE){ printf("book input : \n"); printf(">>도서번호(종료-999) : "); gets(in_num); if (atoi(in_num) >= 999) break; strcpy(blist[idx].num, in_num); //입력 값을 도서번호로 복사 input_rtn(&blist[idx]); //도서정보 입력 함수 호출 idx = idx + 1; }//while output_rtn(blist, idx); //도서정보 출력함수 호출 } //main struct
void input_rtn(btype *blist){ ctype *bp; bp = (ctype *)malloc(sizeof(ctype)); //도서정보 공간확보 printf(">>종 류 : "); gets(bp->kind); printf(">>도 서 명 : "); gets(bp->bname); printf(">>저 자 : "); gets(bp->author); printf(">>요 약 : "); gets(bp->abstract); blist->book = bp; //입력된 도서정보를 대입 } void output_rtn(btype *blist, int idx){ int i; printf("=============================\n"); for (i=0; i < idx; i++, blist++){ printf("도서번호 : "); puts(blist->num); printf("종 류 : "); puts(blist->book->kind); printf("도 서 명 : "); puts(blist->book->bname); printf("저 자 : "); puts(blist->book->author); printf("요 약 : "); puts(blist->book->abstract); printf("=============================\n"); } } <출력결과> >>book input : >>도서번호(999:종료) : 1 >>종 류 : 시 >>도 서 명 : 성산포에서 >>저 자 : 이생진 >>요 약 : 섬마을이야기 >>book input : >>도서번호(999:종료) : 2 >>종 류 : 소설 >>도 서 명 : 압록강은 흐른다 >>저 자 : 이미륵 >>요 약 : 오랜 이국에서의 여정과 어머님에 대한 지극한 사랑과 회고 >>book input : >>도서번호(999:종료) : 999 ============================= 도서번호 : 1 종 류 : 시 도 서 명 : 성산포에서 저 자 : 이생진 요 약 : 섬마을이야기 ============================= 도서번호 : 2 종 류 : 소설 도 서 명 : 압록강은 흐른다 저 자 : 이미륵 요 약 : 오랜 이국에서의 여정과 어머님에 대한 지극한 사랑과 회고 ============================= struct
공용체(Union) 같은 메모리를 서로 다른 데이터형으로 사용하기 위한 데이터 구조 공용체로 선언된 변수들은 한번에 하나의 변수만 사용가능 공용체 정의 구조체와 같은 형태로 정의 공용체 크기는 내부 구성변수 중 가장 큰 것의 크기로 설정 union u_type { char c; int i; double d; } data1; struct
공용체 초기화 • 첫 멤버의 자료형의 초기 값으로만 저장이 가능 • 같은 유형의 변수 값으로 대입 가능 typedef union u_type unionType; unionType data2 = {'A'}; //첫 멤버인 char 유형으로만 초기화 가능 // unionType data1 = {10}; //에러 발생 // unionType data2 = {10.3}; //에러 발생 unionType data3 = data2; //같은 유형의 변수의 값 대입 가능 data3.i = 100; //구성요소를 접근하여 해당 변수형의 값 대입 가능 data3.d = 34.6; //구성요소를 접근하면 해당 변수형의 값 대입 가능 struct
공용체 사용 공용체 변수의 구성요소 접근에 멤버참조연산자(.)이용 공용체 포인터 변수의 구성요소 접근에 간접멤버연산자(->) 이용 //출력결과 u1.c = A, u1.i = 65, u1.d = 0.000 u2.c = A, u2.i = 65, u2.d = 0.000 u1.c = d, u1.i = 100, u1.d = 0.000 u1.c = ? u1.i = 171798692, u1.d = 55.780 struct
//출력결과 u.i = 100, u.f = -106955552.000 u.i = -26214, u.f = 5.300 struct
열거 데이터 유형(enumeration data type) • 연관성 있는 정수형 상수목록 집합을 정의하는 구문 • 요소는 정수 상수 값으로 변경되어 처리 • 0부터 시작하여 1씩 증가된 값이 할당 • 요소에 초기값 부여시 다음 요소는 1증가된 값으로 할당 • 모든 요소에 직접 값 설정 가능 struct
Two + Six = 8 One + Three = 4 Six + Seven = 13 struct
연습문제 (1)별자리를 열거형으로 구성하여 메뉴로 별자리를 선택하면 별자리의 날짜범위를 출력하는 프로그램 작성 • 물병자리 1월20일~2월18일 • 물고기자리 2월19일~3월20일 • 양자리 3월21일~4월19일 • 황소자리 4월20일~5월20일 • 쌍둥이자리 5월21일~6월21일 • 게자리 6월22일~7월22일 • 사자자 7월23일~8월22일 • 처녀자리 8월23일~9월23일 • 천칭자리 9월24일~10월22일 • 전갈자리 10월23일~11월22일 • 사수자리 11월23일~12월24일 • 염소자리 12월25일~1월19일 struct