Presentation is loading. Please wait.

Presentation is loading. Please wait.

프로그래밍실습 제 16 강.

Similar presentations


Presentation on theme: "프로그래밍실습 제 16 강."— Presentation transcript:

1 프로그래밍실습 제 16 강

2 강의 내용 일차원배열 전달의 두 가지 예 이차원배열 전달의 두 가지 예 삼차원배열 전달의 두 가지 예 기억장소의 낭비
기억 장소의 동적 할당(dynamic allocation) malloc의 사용 malloc에 대한 보충 설명 n명의 성적에 대한 평균 계산 동적 할당 테스트 calloc의 사용 calloc에 대한 보충 설명 malloc과 calloc의 차이점 동적 메모리 할당을 이용한 성적 계산 n개의 숫자를 입력받아 이중 홀수만 출력하기

3 일차원배열 전달의 두 가지 예 /* 배열 원소의 합을 구하는 프로그램 */ #include<stdio.h> #define N 5 main() { int a[N]={1,2,3,4,5}; int sum(int[],int),s; s=sum(a,N); printf("합은 %d입니다.\n",s); } int sum(int a[], int n) int i,s=0; for(i=0;i<n;i++) s+=a[i]; return s; 출력: 합은 15입니다. int sum(int*,int),s; int sum(int *a, int n)

4 이차원배열 전달의 두 가지 예 #include<stdio.h> main() { int a[4][3]={{ 1, 2, 3}, { 4, 5, 6}, { 7, 8, 9}, {10,11,12}}; void two(int[][3], int); two(a,4); } void two(int a[][3], int n) int i,j; for(i=0;i<n;i++){ for(j=0;j<3;j++){ a[i][j] *= 2; printf("%4d",a[i][j]); printf("\n"); void two(int (*)[3], int); void two(int (*a)[3], int n)

5 위 프로그램의 출력은 모두 아래와 같다.

6 삼차원배열 전달의 두 가지 예 #include<stdio.h> main() { int a[2][2][2]={1,2,3,4,5,6,7,8}; void two(int [][2][2], int); two(a,2); } void two(int a[][2][2], int n) int i,j,k; for(i=0;i<n;i++){ for(j=0;j<2;j++){ for(k=0;k<2;k++){ a[i][j][k] *= 2; printf("%d ",a[i][j][k]); printf("\n"); void two(int (*)[2][2], int); void two(int (*a)[2][2], int n)

7 위 프로그램의 출력은 모두 아래와 같다.

8 C코드: 08_01.c ~ 08_14b.c 참조

9 평균을 구하는 다음 프로그램의 문제점이 무엇인지 살펴보자.
#include<stdio.h> main() { int a[1000],n,i,s=0; double ave; printf("학생 수는?\n"); scanf("%d",&n); printf("성적을 입력하십시오.\n"); for(i=0;i<n;i++){ scanf("%d",&a[i]); s+=a[i]; } ave=(double)s/(double)n; printf("평균: %.2f\n",ave); 문제점: n이 매우 큰 일반적인 상황에도 프로그램 변경없이 사용 가능하긴 하지만 기억장소의 낭비가 발생한다.

10 기억 장소의 동적 할당(dynamic allocation)
동적 할당을 사용하면 배열의 크기를 프로그램 실행시 정해 줄 수 있다. malloc의 사용: malloc을 사용하여 배열 이름 a인 정수형 일차원 배열을 정의하고 사용하는 경우의 예: #include<stdlib.h> //헤더 파일 stdlib.h(또는 malloc.h)가 필요하다. …… main() { int *a,n; //동적 할당의 경우 일차원 배열의 이름 a는 포인터 변수이다. scanf("%d",&n); a=malloc(n*sizeof(int)); //int형 변수 n개의 기억장소 할당 free(a); //메모리 해제 }

11 malloc에 대한 보충 설명 1. malloc을 사용하기 위해서는 헤더 파일 stdlib.h 또는 malloc.h 가 필요하다. 2. 예를 들어 3개의 원소를 갖는 배열 a를 동적 할당하는 경우 int *a; a=malloc(3*sizeof(int)); 와 같이 하면된다. 이 때 포인터 변수 a에는 a[0]의 주소가 저장된다. (배열을 동적 할당하는 경우 배열 이름은 포인터 상수가 아니다.) 이 경우 캐스트 연산자를 사용하여 다음과 같이 하기도 한다. a=(int *)malloc(3*sizeof(int)); 참고: malloc은 동적할당에 성공한 경우 할당된 공간에 대한 void 포인터를 반환한다. (만일 사용 가능한 메모리가 부족하여 할당에 실패한 경우에는 NULL 포인터를 반환한다.) 즉, 위 문장은 malloc() 함수의 반환값을 void* 형에서 int* 형으로 변경한다.

12 malloc을 사용한 일차원 배열의 동적 할당의 예

13 3. 일반적으로 지역변수는 스택(stack)이라는 메모리 공간에 할당
되지만 동적할당된 변수는 힙(heap)에 저장 된다. 힙은 사용자가 원하는 시점에 메모리 공간을 할당하고 소멸할 수 있도록 마련된 메모리 공간이다. 예를 들어 int *a; a=malloc(100*sizeof(int)); 은 int형 변수 100개의 기억장소를 힙(heap)에 동적 할당한다. 동적할당된 기억장소는 사용이 끝난 뒤에는 반드시 free()를 이용하여 해제해야 한다. 위의 예의 경우 다음과 같이 하여 해제한다. free(a); 4. assert() 함수는 ()안의 내용이 참이면 아무 일도 일어나지 않지만 ()안의 내용이 거짓인 경우에는 프로그램의 실행을 중단하게 하는 함수이다. assert() 함수를 사용하기 위해서는 헤더 파일 assert.h가 필요하다. 참고로 다음 예와 같이 assert() 함수를 사용하면 메모리 할당에 성공했는지 확인 가능하다.

14 #include<stdio.h> #include<malloc.h>
#include<assert.h> main() { int *a,n,i,s=0; double ave; printf("학생 수는?\n"); scanf("%d",&n); a=(int*)malloc(n*sizeof(int)); assert(a!=NULL); // 동적할당에 실패한 경우 프로그램 종료 printf("성적을 입력하십시오.\n"); for(i=0;i<n;i++){ scanf("%d",&a[i]); s+=a[i]; } ave=(double)s/(double)n; printf("평균: %.2f\n",ave); free(a);

15 #include<stdio.h> #include<malloc.h> main() {
위 프로그램은 다음과 같이 바꿀 수도 있다. #include<stdio.h> #include<malloc.h> main() { int *a,n,i,s=0; double ave; printf("학생 수는?\n"); scanf("%d",&n); a=(int*)malloc(n*sizeof(int)); if(a==NULL) return; //동적할당 실패시 프로그램 종료 printf("성적을 입력하십시오.\n"); for(i=0;i<n;i++){ scanf("%d",&a[i]); s+=a[i]; } ave=(double)s/(double)n; printf("평균: %.2f\n",ave); free(a);

16 함수의 호출 끝내기 또는 프로그램의 실행 끝내기
참고: 함수의 호출 끝내기 또는 프로그램의 실행 끝내기

17 동적 할당 테스트 아래 프로그램을 실행시켜 얼마나 큰 n까지 문제 없이 작동하는지 테스트 해 보자.
#include<stdio.h> #include<stdlib.h> #include<assert.h> main() { int *a; __int64 n= ; while(1){ a=(int*)malloc(n*sizeof(int)); assert(a!= NULL); printf("메가바이트 수=%I64d\n",n*4/ ); printf(" 동적메모리 할당\n"); free(a); printf(" 동적메모리 해제\n"); n*=2; }

18 calloc의 사용 calloc을 사용하여 배열 이름 a인 정수형 일차원 배열을 정의하고 사용하는 경우의 예:
#include<stdlib.h> // 헤더 파일 stdlib.h(또는 malloc.h)가 // 필요하다. (calloc.h가 아님에 주의) …… main{() { int *a,n;//동적 할당의 경우 일차원 배열의 이름 a는 포인터 변수이다. scanf("%d",&n); a=calloc(n,sizeof(int));//int형 변수 n개의 기억장소 할당 free(a); //메모리 해제 }

19 calloc에 대한 보충 설명 1. calloc을 사용하기 위해서는 헤더 파일 stdlib.h 또는 malloc.h 가 필요하다. 2. 예를 들어 3개의 원소를 갖는 배열 a를 동적 할당하는 경우 int *a; a=calloc(3,sizeof(int)); 와 같이 하면된다. 이 때 포인터 변수 a에는 a[0]의 주소가 저장된다. (배열을 동적 할당하는 경우 배열 이름은 포인터 상수가 아니다.) 이 경우 캐스트 연산자를 사용하여 다음과 같이 하기도 한다. a=(int *)calloc(3,sizeof(int)); 참고: malloc은 동적할당에 성공한 경우 할당된 공간에 대한 void 포인터를 반환한다. (만일 사용 가능한 메모리가 부족하여 할당에 실패한 경우에는 NULL 포인터를 반환한다.) 즉, 위 문장은 malloc() 함수의 반환값을 void* 형에서 int* 형으로 변경한다.

20 calloc을 사용한 일차원 배열의 동적 할당의 예

21 3. calloc을 사용하여 동적할당된 변수는 malloc과 마찬가지로
힙(heap)에 저장 된다. 예를 들어 int *a; a=calloc(100,sizeof(int)); 은 int형 변수 100개의 기억장소를 힙(heap)에 동적 할당한다. 동적할당된 기억장소는 사용이 끝난 뒤에는 반드시 free()를 이용하여 해제해야 한다. 위의 예의 경우 다음과 같이 하여 해제한다. free(a); 4. 참고로 calloc의 경우에도 assert() 함수를 사용하면 메모리 할당에 성공했는지 확인 가능하다.

22 malloc과 calloc의 차이점 (1) 문법의 차이 예: a=malloc(100*sizeof(int));
a=calloc(100,sizeof(int)); (2) 동적 메모리할당시 malloc : 배열을 초기화 하지 않는다. calloc : 배열을 초기화 한다. 예: 아래 예에서 배열 a의 원소는 초기화되지 않지만 배열 b의 100개의 원소는 모두 0으로 초기화 된다. int *a,*b; a=malloc(100*sizeof(int)); b=calloc(100,sizeof(int)); 주의: 메모리 누출(memory leak)을 막기 위해 메모리 사용이 끝난 후에는 free 명령어를 사용하여 할당된 메모리를 제거한다. 이 때 free(a);는 free(&a[0]);와 같다.

23 동적 메모리 할당을 이용한 성적 계산 /* malloc의 사용 */ #include<stdio.h> #include<stdlib.h> main() { int *a,n,i,s=0; double ave; printf("학생 수는?\n"); scanf("%d",&n); printf("성적을 입력하십시오.\n"); a=malloc(n*sizeof(int)); for(i=0;i<n;i++){ scanf("%d",&a[i]); s+=a[i]; } ave=(double)s/(double)n; printf("평균: %.2f\n",ave); free(a); /* calloc의 사용 */ a=calloc(n,sizeof(int));

24 입출력 예: 학생 수는? 5 성적을 입력하십시오. 평균: 80.20 주의: 위 예에서는 배열의 동적할당시 배열을 초기화할 필요가 없으므로 calloc()보다는 malloc()을 사용하는 것이 바람직하다.

25 예제: n개의 숫자를 입력 받아 이를 일차원 배열에 저장한 뒤 이 숫자
들 중에서 홀수인 것만 한 줄에 출력하는 프로그램을 작성하라. 단, malloc을 사용한 메모리 동적 할당을 이용하라. #include<stdio.h> #include<stdlib.h> main() { int *a,n,i; printf("입력할 숫자의 개수는? "); scanf("%d",&n); a=malloc(n*sizeof(int)); printf("숫자 %d개를 입력하십시오.\n",n); for(i=0;i<n;i++) scanf("%d",&a[i]); printf("홀수: "); if(a[i]%2==1) printf("%d ",a[i]); free(a); }

26 입출력 예: 입력할 숫자의 개수는? 5 숫자 5개를 입력하십시오. 홀수:


Download ppt "프로그래밍실습 제 16 강."

Similar presentations


Ads by Google