프로그래밍실습 제 16 강.

Slides:



Advertisements
Similar presentations
구조체 : Structure 와 포인터 2. 집합적 변수 생성 가능 structure_declaration ::= struct_specifier declarator_list ; struct_specifier ::= struct tag_name | struct tag_name.
Advertisements

스택 스택 추상자료형 스택 스택의 구현 스택의 응용 한빛미디어(주).
컴퓨터 개론 및 실습 강의 9.
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express.
프로그래밍실습 제 7 강.
배열(Array) 선린인터넷고등학교 정보통신과 유 순 옥.
제3장 추가 실습 3장 관련 C 언어 프로그래밍 실습.
Department of Computer Engineering
C 11장. 포인터의 활용 #include <stdio.h> int main(void) { int num;
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
제5장 제어명령
C언어: 배열 (Arrays).
6장. printf와 scanf 함수에 대한 고찰
쉽게 풀어쓴 C언어 Express 제9장 함수와 변수 C Express.
10장 메모리 관리.
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express.
Department of Computer Engineering
25장. 메모리 관리와 동적 할당.
동적메모리와 연결리스트 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
[INA240] Data Structures and Practice
3장. 포인터, 배열, 구조체 포인터, 배열, 구조체 학습목표 기본적 데이터 타입
Dynamic Memory and Linked List
7장 배열 배열의 정의 배열의 초기화 1차원 배열 2차원 및 다차원 배열 문자 배열 배열과 구조.
쉽게 풀어쓴 C언어 Express 제14장 포인터 활용 C Express.
Term Project Team Member
프로그래밍실습 제 17 강.
쉽게 풀어쓴 C언어 Express 제10장 배열 C Express.
6장 배열.
Chapter 13 변수 범위.
쉽게 풀어쓴 C언어 Express 제7장 반복문 C Express.
프로그래밍실습 제 13 강.
CHAP 8:우선순위큐 C로 쉽게 풀어쓴 자료구조 생능출판사 2011.
개정판 누구나 즐기는 C언어 콘서트 제6장 반복문 출처: pixabay.
Chapter 10 함수 기본.
배열과 연결리스트 연결리스트 배열 메모리 할당이 연속적이어서 인덱스 사용시 검색이 빠르다.
다음 주 과제 3장 읽어오기 숙제 해서 제출하기. 자료구조와 알고리즘, 순환 E304호,
Chapter 04 리스트.
Chap. 1 Data Structure & Algorithms
함수와 변수 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
제어문 & 반복문 C스터디 2주차.
CHAP 2:순환.
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
많은 자료가 있을 때는 배열을 사용한다. 아래는 배열을 사용하는 경우의 예시이다. 상황에 따라 1차원 또는 다차원 배열 필요.
Chapter 11. 배열과 포인터.
Part 09 배열 안산1대학 디지털정보통신과 임 성 국.
실습과제 1(조건문, ) 표준입력으로 수축기 혈압을 입력 받아 그에 따른 적당한 표현을 화면에 출력하는 프로그램을 if-else 문을 이용하여 작성.
Chapter 4 변수 및 바인딩.
#1 배열 활용 #include int main(void) { int i; int grade[5]; grade[0] = 10; grade[1] = 20; grade[2] = 30; grade[3] = 40; grade[4] = 50; for(i=0;i.
-Part2- 제1장 1차원 배열이란 무엇인가.
6장 반복제어문 for 문 while 문 do while 문 기타 제어문.
CHAP 8:우선순위큐.
Department of Computer Engineering
-Part1- 제7장 반복문이란 무엇인가.
03. 메모리 관리 C++ 프로그램에서 다룰 수 있는 메모리의 종류
컴퓨터 프로그램은 여러 기능의 복합체이다. 라이브러리 함수와 사용자 정의 함수
쉽게 풀어쓴 C언어 Express 제6장 조건문 C Express.
자료구조 세미나 발표 주제: 자료구조 기초 - 1회 차: 자료구조의 정의, 기초 지식 (함수, 포인터, 레퍼런스)
1학기 정리 지난 학기에 배운 내용을 복습해 본다..
-Part2- 제2장 다차원 배열이란 무엇인가.
실습과제 1번 생성된 파일 basic.txt를 프로젝트 폴더에서 메모장으로 열고 내용을 확인
9주차: Using Files and Others
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
어서와 C언어는 처음이지 제16장.
C 13장. 입출력 라이브러리 #include <stdio.h> int main(void) { int num;
C.
어서와 C언어는 처음이지 제22장.
개정판 누구나 즐기는 C언어 콘서트 제12장 파일 입출력 출처: pixabay.
배열, 포인터, 함수 Review & 과제 1, 2.
⊙ 입출력 처리란? data를 입력장치로부터 program 내부로 읽어 들이거나
Presentation transcript:

프로그래밍실습 제 16 강

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

일차원배열 전달의 두 가지 예 /* 배열 원소의 합을 구하는 프로그램 */ #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)

이차원배열 전달의 두 가지 예 #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)

위 프로그램의 출력은 모두 아래와 같다. 2 4 6 8 10 12 14 16 18 20 22 24

삼차원배열 전달의 두 가지 예 #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)

위 프로그램의 출력은 모두 아래와 같다. 2 4 6 8 10 12 14 16

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

평균을 구하는 다음 프로그램의 문제점이 무엇인지 살펴보자. #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이 매우 큰 일반적인 상황에도 프로그램 변경없이 사용 가능하긴 하지만 기억장소의 낭비가 발생한다.

기억 장소의 동적 할당(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); //메모리 해제 }

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* 형으로 변경한다.

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

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

#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);

#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);

함수의 호출 끝내기 또는 프로그램의 실행 끝내기 참고: 함수의 호출 끝내기 또는 프로그램의 실행 끝내기 http://dasan.sejong.ac.kr/~yjcha/c1/c_lectures/ch_08_exit_abort_assert.hwp

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

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); //메모리 해제 }

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* 형으로 변경한다.

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

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

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]);와 같다.

동적 메모리 할당을 이용한 성적 계산 /* 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));

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

예제: 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); }

입출력 예: 입력할 숫자의 개수는? 5 숫자 5개를 입력하십시오. 12 743 893 82 111 홀수: 743 893 111