Microsoft PowerPoint - 2주_강의노트

Similar documents
금오공대 컴퓨터공학전공 강의자료

슬라이드 1

Data Structure

학습목차 2.1 다차원배열이란 차원배열의주소와값의참조

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

PowerPoint 프레젠테이션

Microsoft PowerPoint - chap06-2pointer.ppt

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

11장 포인터

Microsoft PowerPoint - ch07 - 포인터 pm0415

설계란 무엇인가?

Microsoft PowerPoint - chap06-5 [호환 모드]

A Dynamic Grid Services Deployment Mechanism for On-Demand Resource Provisioning

금오공대 컴퓨터공학전공 강의자료

<322EBCF8C8AF28BFACBDC0B9AEC1A6292E687770>

Microsoft PowerPoint - chap06-1Array.ppt

untitled

목차 포인터의개요 배열과포인터 포인터의구조 실무응용예제 C 2

1 장 C 언어복습 표준입출력배열포인터배열과포인터함수 const와포인터구조체컴파일러사용방법 C++ 프로그래밍입문

Microsoft PowerPoint - [2009] 02.pptx

11장 포인터

제 14 장포인터활용 유준범 (JUNBEOM YOO) Ver 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다.

윤성우의 열혈 TCP/IP 소켓 프로그래밍

슬라이드 1

구조체정의 자료형 (data types) 기본자료형 (primitive data types) : char, int, float 등과같이 C 언어에서제공하는자료형. 사용자정의자료형 (user-defined data types) : 다양한자료형을묶어서목적에따라새로운자료형을

Microsoft PowerPoint - 제11장 포인터(강의)

Microsoft PowerPoint - chap-11.pptx

Microsoft PowerPoint - 제11장 포인터

이번장에서학습할내용 동적메모리란? malloc() 와 calloc() 연결리스트 파일을이용하면보다많은데이터를유용하고지속적으로사용및관리할수있습니다. 2

제 11 장포인터 유준범 (JUNBEOM YOO) Ver 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다.

PowerPoint 프레젠테이션

KNK_C_05_Pointers_Arrays_structures_summary_v02

C 언어 프로그래밊 과제 풀이

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

중간고사

Microsoft PowerPoint - additional01.ppt [호환 모드]

Microsoft PowerPoint - chap11-포인터의활용.pptx

02장.배열과 클래스

Microsoft PowerPoint - Chapter 6.ppt

Microsoft PowerPoint - chap10-함수의활용.pptx

Microsoft PowerPoint - Chapter_08.pptx

1. auto_ptr 다음프로그램의문제점은무엇인가? void func(void) int *p = new int; cout << " 양수입력 : "; cin >> *p; if (*p <= 0) cout << " 양수를입력해야합니다 " << endl; return; 동적할

Microsoft PowerPoint - 3ÀÏ°_º¯¼ö¿Í »ó¼ö.ppt

설계란 무엇인가?

Microsoft PowerPoint - C++ 5 .pptx

OCW_C언어 기초

PowerPoint Template

Microsoft PowerPoint - Java7.pptx

Microsoft PowerPoint - 8ÀÏ°_Æ÷ÀÎÅÍ.ppt

Microsoft PowerPoint - chap13-입출력라이브러리.pptx

<4D F736F F F696E74202D20C1A63132B0AD20B5BFC0FB20B8DEB8F0B8AEC7D2B4E7>

Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100

OCW_C언어 기초

C++ Programming

PowerPoint 프레젠테이션

The C++ Programming Language 5 장포인터, 배열, 구조체 5.9 연습문제 다음의선언문을순서대로작성해보자. 문자에대한포인터, 10개정수의배열, 10개정수의배열의참조자, 문자열의배열에대한포인터, 문자에대한포인터에대한포인터, 상수정수, 상수

Infinity(∞) Strategy

ch15

PowerPoint Presentation

Lab 3. 실습문제 (Single linked list)_해답.hwp

1. 표준입출력 C++ : C의모든라이브러리를포함 printf, scanf 함수사용가능예 : int, double, 문자열값을입력받고출력하기 #include <cstdio> int ivar; double dvar; char str[20]; printf("int, dou

PowerPoint Presentation

PowerPoint Presentation

PowerPoint Template

C++ Programming

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

쉽게 풀어쓴 C 프로그래밍

Chapter 4. LISTS

Microsoft PowerPoint - ch07 - 포인터 pm0415

PowerPoint 프레젠테이션

Microsoft PowerPoint - additional06.ppt [호환 모드]

비트와바이트 비트와바이트 비트 (Bit) : 2진수값하나 (0 또는 1) 를저장할수있는최소메모리공간 1비트 2비트 3비트... n비트 2^1 = 2개 2^2 = 4개 2^3 = 8개... 2^n 개 1 바이트는 8 비트 2 2

Microsoft PowerPoint - Chapter 1-rev

<4D F736F F F696E74202D20C1A63137C0E520B5BFC0FBB8DEB8F0B8AEBFCD20BFACB0E1B8AEBDBAC6AE>

歯9장.PDF

A Hierarchical Approach to Interactive Motion Editing for Human-like Figures

<4D F736F F F696E74202D20C1A63134C0E520C6F7C0CEC5CD5FC8B0BFEB>

Microsoft PowerPoint - 03_(C_Programming)_(Korean)_Pointers

3. 1 포인터란 3. 2 포인터변수의선언과사용 3. 3 다차원포인터변수의선언과사용 3. 4 주소의가감산 3. 5 함수포인터

4. 1 포인터와 1 차원배열 4. 2 포인터와 2 차원배열 4. 3 포인터배열 4. 4 포인터와문자그리고포인터와문자열

Microsoft PowerPoint - chap03-변수와데이터형.pptx

프입2-강의노트-C++기초

Microsoft PowerPoint - additional08.ppt [호환 모드]

쉽게 풀어쓴 C 프로그래밍

PowerPoint Template

Microsoft PowerPoint - C프로그래밍-chap03.ppt [호환 모드]

PowerPoint 프레젠테이션

8장. 포인터

K&R2 Reference Manual 번역본

1. 객체의생성과대입 int 형변수 : 선언과동시에초기화하는방법 (C++) int a = 3; int a(3); // 기본타입역시클래스와같이처리가능 객체의생성 ( 복습 ) class CPoint private : int x, y; public : CPoint(int a

PowerPoint Presentation

슬라이드 1

6.1 Addresses and Pointers Recall memory concepts from Ch2 ch6_testbasicpointer.c int x1=1, x2=7; double distance; int *p; int q=8; p = &q; name addre

< E20C6DFBFFEBEEE20C0DBBCBAC0BB20C0A7C7D12043BEF0BEEE20492E707074>

The C++ Programming Language 4 장타입과선언 4.11 연습문제 Hello,world! 프로그램을실행시킨다. 프로그램이컴파일되지않으면 B3.1 을참고하자. #include<iostream> //#include 문, 헤더파일, 전처리지시

C++ Programming

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CC0E7B0EDB0FCB8AE5C53746F636B5F4D616E D656E74732E637070>

Microsoft PowerPoint - Chapter_04.pptx

Microsoft PowerPoint 자바-기본문법(Ch2).pptx

Lab 4. 실습문제 (Circular singly linked list)_해답.hwp

Transcription:

C++ 프로그래밍 강의노트 #2: C 언어복습 - 포인터와함수에대한이해 - 함수포인터와 void 포인터 - 구조체 - 2장메모리구조와동적할당 - 실습문제 2007. 3. 14 담당교수 : 조재수 E-mail: jaesoo27@kut.ac.kr 강의노트 Download 사이트 : http://ime.kut.ac.kr/jaesoo 1 학습목표 C 언어복습 1장포인터 (Pointer) 와배열, 구조체의이해 - 포인터와함수에대한이해 - 함수포인터와 void 포인터 - 포인터의포인터 ( 더블포인터 ) - 구조체 - 실습문제 2/62 1

포인터와함수에대한이해 3 1-3 포인터와함수에대한이해 1. 함수의인자로배열전달하기 기본적인인자의전달방식 값의복사에의한전달 그림 1-11: 함수에인자전달의기본원리 4/62 2

1-3 포인터와함수에대한이해 1. 함수의인자로배열전달하기 배열의함수인자전달방식 배열이름 ( 배열주소, 포인터 ) 에의한전달 #include <stdio.h> void fct(int *arr2); int arr1[2]=1, 2; fct(arr1); printf("%d n", arr1[0]); void fct(int *arr2) printf("%d n", arr2[0]); arr2[0]=3; 그림 1-12: 함수의인자로배열전달하기 5/62 1-3 포인터와함수에대한이해 1. 함수의인자로배열전달하기 배열이름, 포인터의 sizeof 연산 배열이름 : 배열전체크기를바이트단위로반환 포인터 : 포인터의크기 (4) 를바이트단위로반환 #include <stdio.h> int arr[5]; int* parr=arr; printf( %d n, sizeof(arr) ); printf( %d n, sizeof(parr) ); // 20 출력 // 4 출력 6/62 3

1-3 포인터와함수에대한이해 1. 함수의인자로배열전달하기 "int * parr" vs. "int parr[ ]" 둘다같은의미를지닌다. 선언 "int parr[ ]" 은함수의매개변수선언시에만사용가능 예제 1-14.c: 배열을함수인자로전달하는방법 1: /* 예제 1-14.c */ 2: #include <stdio.h> 3: 4: void fct(int *arr2); 5: 6: 7: 8: int arr1[2]= 1, 2 ; 9: 10: fct(arr1); 11: printf("%d n", arr1[0]); 12: 13: 14: 16: void fct(int *arr2) 17: 18: printf("%d n", arr2[0]); 19: arr2[0]=3; 20: 배열의이름을함수의인자로전달 : 배열이름은첫번째요소의주소값을의미하는상수포인터 7/62 1-3 포인터와함수에대한이해 [ 그림 1-19] 함수의인자로배열전달하기 8/62 4

1-3 포인터와함수에대한이해 1: /* 예제 1-15.c */ 2: #include <stdio.h> 3: 4: int ArrAdder(int* parr, int n); 5: 6: 7: 8: int arr[10]=1, 2, 3, 4, 5, 6, 7, 8, 9, 10; 9: int SumOfArr; 10: 11: SumOfArr=ArrAdder(arr, sizeof(arr)/sizeof(int)); 12: printf(" 배열의총합 :%d n", SumOfArr); 13: 14: 15: 16: 17: int ArrAdder(int* parr, int n) 18: 19: int sum=0; 20: int i; 21: 22: for(i=0; i<n; i++) 23: sum+=parr[i]; 24: 25: return sum; 26: 11번째줄에서 sizeof 연산자를배열의이름에사용하게되면, 배열의크기 ( 총바이트수 ) 가반환 함수ArrAdder호출시첫번째인자 ( 배열의주소 ) 만전달할경우함수내에서는배열의길이를알방법이없다. 9/62 1-3 포인터와함수에대한이해 1: /* max_fct.c */ 2: #include <stdio.h> 3: 4: int MaxVal(int parr[], int n); 5: 6: 7: 8: int arr[10]=4, 8, 3, 7, 2; 9: int max; 10: 11: max=maxval(arr,sizeof(arr)/sizeof(int)); 12: printf(" 최대값 : %d n", max); 13: 14: 15: 16: 17: int MaxVal(int parr[], int n) 18: 19: int max, i; 20: max=parr[0]; 21: 22: for(i=1; i<n; i++) 23: if(max<parr[i]) 24: max=parr[i]; 25: return max; 27: 17번째줄에서 intparr[] 와int*pArr은완전히같은표현 int parr[] 표현은함수의매개변수를선언할때에만가능 10/62 5

참고 : Call-By-Value와 Call-By-Reference Call-By-Value 값의복사에의한함수의호출 가장일반적인함수호출형태 #include <stdio.h> int add(int a, int b); int val1=10; int val2=20; printf(" 결과 : ", add(val1, val2); int add(int a, int b) return a+b; 11/62 참고 : Call-By-Value와 Call-By-Reference Call-By-Value에의한 swap int val1=10; int val2=20; swap(val1, val2); printf("val1 : %d n", val1); printf("val2 : %d n", val2); void swap(int a, int b) int temp=a; a=b; b=temp; printf("a : %d n", a); printf("b : %d n", b); 그림 1-13: 값이변경되지않는이유 12/62 6

참고 : Call-By-Value와 Call-By-Reference Call-By-Reference 참조 ( 참조를가능케하는주소값 ) 를인자로전달하는형태의함수호출 그림 1-14: Call-By-Reference 의기본원리 13/62 참고 : Call-By-Value 와 Call-By-Reference Call-By-Reference 에의한 swap int val1=10; int val2=20; printf("before val1 : %d n", val1); printf("before val2 : %d n", val2); swap(&val1, &val2); //val1, val2 주소전달 printf("after val1 : %d n", val1); printf("after val2 : %d n", val2); void swap(int* a, int* b) int temp=*a; *a=*b; *b=temp; 그림 : 값의변경절차 14/62 7

1-3 포인터와함수에대한이해 2. 포인터와 const 키워드 포인터가가리키는변수의상수화 int a = 10; const int * p = &a; *p=30 // Error! a=30 // OK! 포인터상수화 int a=10; int b=20; int * const p = &a; p=&b // Error! *p=30 // OK! 15/62 1-3 포인터와함수에대한이해 2. 포인터와 const 키워드 const 키워드를사용하는이유 컴파일시잘못된연산에대한에러메시지 프로그램을안정적으로구성 #include <stdio.h> float PI=3.14; #include <stdio.h> const float PI=3.14; float rad; PI=3.07; // 분명히실수!! float rad; PI=3.07; // Compile Error 발생! scanf("%f", &rad); printf(" 원의넓이는 %f n", rad*rad*pi); scanf("%f", &rad); printf(" 원의넓이는 %f n", rad*rad*pi); 16/62 8

함수포인터와 void 포인터 17 1-4 함수포인터와 Void 포인터 1. 함수포인터 함수포인터는메인메모리에올라와있는함수를가리킬수있는포인터 함수의이름은메모리상에존재하는함수의위치를가리키는포인터 함수포인터의포인터타입은어떻게되는가? 그림 1-20: 함수와함수포인터에대한이해 18/62 9

1-4 함수포인터와 Void 포인터 함수이름의포인터타입을결정짓는요소 리턴타입 + 매개변수타입 적절한함수포인터의선언 int fct1 (int a) a++ return a; int (*fptr1) (int); int 형인자 1 개를받는다. 리턴형은 int 형이다. fptr1 은포인터이다. double fct2 (double a, double b) double add=a+b; return add; double (*fptr2) (double, double); 19/62 1-4 함수포인터와 Void 포인터 1: /* 예제1-17.c */ 2: #include <stdio.h> 3: 4: void SelFunction(int s); 5: void Add(void); 6: void Min(void); 7: 8: 9: 10: int sel; 11: 12: while(1) 13: 14: printf(" 선택 : 덧셈 (1), 뺄셈 (2), 종료 (3) "); 15: scanf("%d", &sel); 16: if(sel==3) 17: break; 18: SelFunction(sel); 19: 20: printf(" 프로그램이종료되었습니다. n"); 21: 22: 23: 24: 25: void SelFunction(int s) 26: 27: void (*fptr)(void); 28: if(s==1) 29: fptr=add; 30: else 31: fptr=min; 32: fptr(); // 이부분의의미는? 이부분이없다면? 33: 34: 35: void Add(void) 36: 37: int a, b; 38: printf(" 덧셈을위한두개의숫자입력 : "); 39: scanf("%d %d", &a, &b); 40: printf(" 덧셈결과 : %d n n", a+b); 41: 42: void Min(void) 43: 44: int a, b; 45: printf(" 뺄셈을위한두개의숫자입력 : "); 46: scanf("%d %d", &a, &b); 47: printf(" 뺄셈결과 : %d n n", a-b); 48: 20/62 10

1-4 함수포인터와 Void 포인터 // fct_ptr2.c 1: #include <iostream> 2: using namespace std; 3: 4: void strange (void (*ptrtofunction)()); 5: void fun(); 6: void pun(); 7: void sun(); 8: 9: int main() 10: 11: strange (fun); 12: strange (pun); 13: strange (sun); 14: 15: 16: 17: void strange(void(*ptrtofunction)()) 18: 19: (*ptrtofunction)(); // ptrtofunction(); O.K.? 20: return; 21: 22: 23: void fun() 24: 25: printf("fun is being with good friends. n"); 26: return; 27: 29: 30: void pun() 31: 32: printf("pun is a play on words. n"); 33: return; 34: 35: 36: void sun() 37: 38: printf(" Sun is a bright star. n"); 39: return; 40: ptrtofunction은매개변수가없고, 리턴값을가지지않는함수에대한포인터이다. 함수이름은포인터상수이다. 21/62 1-4 함수포인터와 Void 포인터 4. void형포인터란무엇인가? 자료형에대한정보가제외된, 주소정보를담을수있는형태의변수 포인터연산, 메모리참조와관련된일에활용할수없다. char c= a ; int n=10; void * vp; vp=&c; vp=&n;..... // void 포인터선언 int n=10; void * vp=&n; *vp=20; vp++;..... // Error! // Error! 22/62 11

1-4 함수포인터와 Void 포인터 4. void 형포인터란무엇인가? Void 포인터는결국명시적형변환과정을거쳐서사용하게된다. 일단주소값을저장해두고, 포인터타입은나중에결정한다. 메모리의동적할당에서유용하게사용된다. int n=10; void *vp = &n ; *((int*) vp) = 20;..... // void 포인터선언및초기화 // n 값을변경하기위해서 int 형포인터로형변환 23/62 1-5 포인터의포인터 포인터의포인터 ( 더블포인터 ): 싱글포인터의주소값을저장하기위한용도로사용되는포인터 24/62 12

1-5 포인터의포인터 1: #include <iostream> 2: using namespace std; 3: // or #include <stdio.h> 4: int main() 5: 6: int a; 7: int* p; 8: int** q; 9: int*** r; 10: 11: p = &a; 12: q = &p; 13: r = &q; 14: 15: a = 10; 16: printf(" a = %d *p = %d **q = %d ***r = %d n", a, *p, **q, ***r); 17: 19: [ 그림 1-17] 포인터의포인터사용하기 25/62 연습문제 1-11 그림 1-24 와같은구조를생성하는프로그램을작성하여라. a, b, c 의데이터를포인터 p, q, r 을이용하여읽어라. p q r a b c 그림 1-24: 연습문제 1-11 의데이터구조 데이터를읽은후에프로그램에서 p 는 c 를 q 는 a 를 r 은 b 를가리키도록재지정하여라. 지정이끝난후에각각의변수를포인터를사용하여출력하여라. 각변수마다값과그것의주소를출력하여라. 26/62 13

구조체 (Structure) 의이해 27 1.6 구조체 (structure) 구조체란하나이상의변수 ( 기본자료형 ) 를그룹지어서새로운자료형을정의하는것이다. 구조체는서로다른자료형을묶어만든새로운자료형으로프로그램에서사용하려면다음과같은형식으로변수를선언해야한다. struct 구조체명 표준자료형1 멤버변수 ; 표준자료형2 멤버변수 ;...... ; 주의할점 : 구조체멤버변수를선언할때초기값을줄수없다. 구조체는자료형의틀만구성하는것이므로구조체내부의멤버변수도역시자료형을구성하는구조만을알려줄뿐이다. 구조체선언과정은메모리할당과정이일어나는것이아니므로실질적인값은저장하지못한다. 28/62 14

1.6 구조체 (structure) 학생성적관리프로그램을위한구조체를정의해보자. 구조체는세가지의학생정보 ( 이름, 학번, 최근 2 학기평점 ) 를구조체멤버로구성 구조체명 (tab 명 ) 은 StudentInfo 로하고, 각멤버변수명은 name, stdnumber, grade 로선언한다. struct StudentInfo char name[20]; // 학생이름 int stdnumber; // 학번 float grade[2]; // 최근 2학기평점 ; 구조체변수선언방식 struct 구조체명구조체변수명 1, 구조체변수명 2,... 구조체변수명 n; struct StudentInfo student1, student2; 29/62 1.6 구조체 (structure) [ 예제 1-4] #include <iostream> using namespace std; // 학생정보를갖는구조체 struct StudentInfo char name[20]; // 이름 int stdnumber; // 학번 float grade[2]; // 최근 2학기평점 ; void PrnStudent(StudentInfo stdinfos[], int n) // 학생정보를출력하는함수 // 학생의정보를출력해본다. for (int i = 0; i < n; ++i) printf(" 이름 :%s, 학번 : %d, 1학기학점 : %5.3f, 2학기학점 : %5.3f n", stdinfos[i].name, stdinfos[i].stdnumber, stdinfos[i].grade[0], stdinfos[i].grade[1]); void PrnStudent(StudentInfo stdinfos[ ], int n); int main() // 5 명의학생정보를담을배열을만들고 // 학생정보를초기화한다. StudentInfo stdinfos[5] = "Kim Chol-Su", 200121233, 3.2f, 3.5f, "Lee Chol-Su", 200223517, 4.5f, 4.5f, "Park Chol-Su", 200321131, 1.7f, 2.0f, "Yang Chol-Su", 200222289, 0.4f, 4.1f, "Yoon Chol-Su", 199921444, 2.7f, 2.8f ; PrnStudent(stdInfos, sizeof(stdinfos)/sizeof(studentinfo)); 구조체포인터변수와완전히같은표현 StudentInfo stdinfos[] = StudentInfo *stdinfos 함수의매개변수를포인터로수정하여프로그램을다시실행해보자. 30/62 15

1.6 구조체 (structure) [ 예제 1-5] // 예제 1-5.cpp #include <iostream> using namespace std; struct funstr int id; // 구조체변수마다갖는고유한값 funstr* p; // 자신과같은 funstr 구조체를가리키는포인터멤버 ; int main() // funstr 구조체변수를 3 개선언하고, 서로를가리키도록만든다. funstr a, b, c; a.id = 1; a.p = &b; b.id = 2; b.p = &c; c.id = 3; c.p = &a; [ 그림 1-25] funstr 구조체변수 a, b, c 의모습 // a 만사용해서 a, b, c 모두에접근한다. printf("a.id = %d n", a.id); 31/62 실습문제 1 길이가 10 인배열을선언하고, 총 10 개의정수를입력받는다. 단입력받은숫자가홀수이면배열의앞에서부터채워나가고, 짝수이면뒤에서부터채워나가는형식을취하기로하자. 따라서사용자가 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 을입력했다면, 배열에는 [1, 3, 5, 7, 9, 10, 8, 6, 4, 2] 의순으로저장이될것이다. 실행예 ) 총 10 개의숫자입력 >1 >1 >4 >4 >4 >4 >3 >3 >2 >2 배열요소의출력 : 1 1 3 3 2 2 4 4 4 4 32/62 16

실습문제 2 길이가 10 인배열을선언하고, 총 10 개의정수를입력받아서, 홀수와짝수를구분지어서출력하는프로그램을작성해보자. 일단홀수부터출력하고나서, 짝수를출력하도록하자. 단 10 개의정수는 main 함수내에서입력받도록하고, 배열을인자로받아서배열내에존재하는홀수만을출력하는함수와짝수만을출력하는함수를각각정의해서이함수들을호출하는형식으로프로그램을작성하자. 실행의예 ) 총 10 개의숫자입력 >1 >2 >3 >4 >5 >6 >7 >8 >9 >0 홀수출력 : 1, 3, 5, 7, 9 짝수출력 : 2, 4, 6, 8, 0 33/62 실습문제 3 다음은어느인터넷사이트사용자에대한정보이다. 이러한사용자정보를표현할수있는구조체를정의하고, 초기화한후, 모든사용자정보를모니터에출력하는함수를포함하는프로그램을작성해보자. 초기화는사용자정보가기록되어있는파일정보 (user.txt) 를개방하여 (open) 초기화하고, 사용자전체를출력하는함수 (PrnUser(..)) 의매개변수는포인터를사용하여출력하도록하자. user.txt 파일내용은차례대로 아이디 비밀번호 5개스테이지별점수 마법포인트 체력포인트 --------------------------------------------------------- denzang sd933k 80 56 72 86 91 300 10010 zzazang!@sd487 100 98 100 100 91 20000 19000 gochuzang df321#4 34 54 70 48 54 400 5000 --------------------------------------------------------- 34/62 17

2장학습목표 C 언어복습 메모리관리와동적할당 -메모리구조 -메모리동적할당 35/62 2 장. 메모리관리와동적할당 36 18

2-1 C 언어의메모리구조 - [1] 스택, 힙그리고데이터영역 Program Code 프로그램 (code) 영역 그림 2-1: 메모리의개념적인 View 메모리공간의할당시기 : 프로그램이실행될때마다 메모리공간이할당되는장소 : 메인메모리 (RAM) 할당용도 : 프로그램실행시필요한메모리공간을위해서 누가할당하는가? 컴퓨터운영체제 (OS) 그림 2-2: C/C++ 언어의메모리관리구조 37/62 2-1 C 언어의메모리구조- [1] 스택, 힙그리고데이터영역 스택, 힙그리고데이터영역 프로그램의실행을위해기본적으로할당하는메모리공간 컴파일타임에함수에서요구하는스택의크기결정되어야함 데이터영역 (Data Area) 전역변수와 static 변수가할당되는영역 프로그램의시작과동시에할당되고, 프로그램이종료되어야만메모리에서소멸된다. 스택영역 (Stack Area) 함수호출시생성되는지역변수와매개변수가저장되는영역 함수호출이완료되면사라진다. 38/62 19

2-1 C 언어의메모리구조 - 스택, 힙그리고데이터영역 힙영역 (Heap Area) 힙은프로그래머가관리하는메모리영역 프로그래머의필요에의해서메모리공간이할당및소멸되는영역 프로그램이실행될때까지는알수없는가변적인량만큼의데이터량을저장하기위해프로그램의프로세서가사용할수있도록미리예약되어있는메인메모리의영역 프로그램영역 (Code Area) 프로그램코드가저장되는영역 39/62 2-1 C 언어의메모리구조 [2] 프로그램의실행과메모리할당의흐름 /* memory.c */ void fct1(int); void fct2(int); int a=10; int b=20; int main (void) int m=123; 첫번째 : 프로그램의시작그리고전역변수의저장 fct1(m); fct2(m); void fct1(int c) int d=30; void fct2(int e) int f=40; 그림 2-3: 데이터영역의초기화 스택영역 : 총 20 byte 의메모리가필요 지역변수 : m, f, d, 매개변수 : c, e 40/62 20

[2] 프로그램의실행과메모리할당의흐름 두번째 : main 함수의호출 세번째 : fct1 함수의호출 main m=123 fct1 main c=123, d=30 m=123 그림 2-4: main 함수의지역변수를위한스택의할당 그림 2-5: fct1 함수의매개변수와지역변수를위한스택의할당 41/62 [2] 프로그램의실행과메모리할당의흐름 네번째 : fct1 함수의완료그리고 fct2 함수의호출 삭제 fct1 main c=123, d=30 m=123 fct2 main e=123, f=40 m=123 (a) fct1 함수실행완료시 (b) fct2 함수실행시 그림 2-6: fct1 함수실행완료그리고 fct2 함수의호출시 42/62 21

[2] 프로그램의실행과메모리할당의흐름 다섯번째 : fct2 함수의완료, main 함수의완료그리고프로그램의종료 fct2 main e=123, f=40 m=123 그림 2-7: 프로그램의종료 43/62 2-1 C 언어의메모리구조 - [3] 힙영역의필요성 1: /* ProbArray.c */ 2: 3: #include <stdio.h> 4: 5: void function(int); 6: 7: 8: 9: int m = 0; 10: scanf("%d", &m); // 배열의길이입력받음 11: function(m); // 배열의길이전달 12: 13: 14: 15: 16: void function(int i) 17: 18: int array[i]; // 입력받은길이만큼배열할당 19: 예제 ProbArray.c에서잘못된부분은? 배열선언시반드시상수만사용해야하는이유는? 44/62 22

2-1 C 언어의메모리구조 - [3] 힙영역의필요성 배열선언시반드시상수만사용해야하는이유는? 스택과데이터영역에할당된메모리의크기는컴파일되는동안 (compile-time) 에결정되어야한다. 할당해야할메모리의크기를런-타임에결정해야하는경우, 유용하게사용되는메모리공간이바로힙영역이다. 1: /* ProbArray.c */ 2: 3: #include <stdio.h> 4: 5: void function(int); 6: 7: 8: 9: int m = 0; 10: scanf("%d", &m); // 배열의길이입력받음 11: function(m); // 배열의길이전달 12: 13: 14: 15: 16: void function(int i) 17: 18: int array[i]; // 입력받은길이만큼배열할당 19: 45/62 2-1 C 언어의메모리구조 - [3] 힙영역의필요성 배열의선언 배열의길이선언은상수! 컴파일타임에요구되는메모리공간의크기를결정지어야한다. /* ProbArray2.c? */ #include <stdio.h> 예제 ProbArray2.c에서 function 함수는에러가있는가? 문제가있다면이유는? void function(); int m = 0; function(); // 배열의길이전달 void function() int i = 10; // 4 바이트 int array[i]; // 40 바이트예상 46/62 23

2-1 C 언어의메모리구조 - [3] 힙영역의필요성 예제 ProbArray2.c에서 function 함수는에러가있는가? 문제가있다면이유는? -> 지역변수 i 가 10으로초기화되는순간은컴파일되는동안 (compiletime) 이아니라, 실행되는동안 (runtime) 에결정된다. 할당해야할메모리의크기를런-타임 ( 프로그램이실행되는동안 ) 에결정해야하는경우, 유용하게사용되는메모리공간이힙 (Heap) 영역이다. /* ProbArray2.c? */ #include <stdio.h> void function(); int m = 0; function(); // 배열의길이전달 void function() int i = 10; // 4 바이트 int array[i]; // 40 바이트예상 47/62 2-2 메모리동적할당 메모리동적할당 런 - 타임에메모리공간의크기를결정지어서할당 ( 힙영역에할당 ) #include <stdlib.h> void* malloc(size_t size) 성공시할당된메모리의첫번째주소리턴, 실패시 NULL 포인터리턴 참고 ) 메모리의첫번째주소를리턴한다면힙에할당한배열이나변수에접근하려면포인터를사용해야한다. 스택과데이터영역에메모리를할당하는것을두고 정적할당 (static allocation) 이라한다. 동적할당된메모리공간의소멸 #include <stdlib.h> void free(void* ptr) 48/62 24

2-2 메모리동적할당 malloc 함수의리턴형이 void* (void 포인터 ) 인이유는무엇인가? 리턴할영역을무엇으로할지에대하여결정하여야한다. malloc 함수호출시전달하는인자정보만을가지고는리턴해야할주소값의포인터타입을결정짓지못한다. 사용자는리턴된포인터를가지고용도에맞게포인터를형변환해서사용 49/62 2-2 메모리동적할당 malloc 함수의활용 malloc&free.c, ProbArray2.c 참조 그림 2-8: malloc 함수의호출 50/62 25

2-2 메모리동적할당 힙은프로그래머가관리하는메모리공간이므로메모리를해제하는것도프로그래머가신경써야할내용 동적할당된메모리공간의소멸 ( 해제 ) 필요 free 함수이용 1: /* malloc&free.c */ 2: #include <stdio.h> 3: #include <stdlib.h> 4: 5: int main (void) 6: 7: int* a; 8: a=(int*)malloc(sizeof(int)); // 메모리할당. 9: if(a==null) // 메모리할당의성공유무확인 10: 11: puts(" 메모리할당에실패!"); 12: exit(1); 13: 14: 15: *a=20; 16: printf(" 힙에저장된변수 a : %d n", *a); 17: free(a); // 메모리해제. 18: 19: 51/62 2-2 메모리동적할당 /* ProbArray2.c */ #include <stdio.h> #include <stdlib.h> void function(int i) //int array[i]; // ProbArray.c 에서의문제점. // 동적메모리할당. int* array =(int*)malloc(sizeof(int)*i); int j; void function(int); int main (void) int m=0; fputs(" 배열의크기를입력하세요 : ", stdout); scanf("%d", &m); function(m); if(array==null) puts(" 메모리할당에실패!"); exit(1); /* 동적할당한메모리사용 */ for(j=0; j<i; j++) array[j]=j+1; for(j=0; j<i; j++) printf("%d ", array[j]); printf(" n"); free(array); // 할당된메모리소멸. 52/62 26

연습문제 2-2 1. 사용자로부터문자열을입력받고출력하는프로그램을작성해보자. 단! 문자열을입력받기전에입력할문자열의최대길이를먼저입력받기로하자. 그리고, 그길이만큼메모리를동적으로 (malloc 함수사용 ) 할당해서문자열을입력받아야한다. 실행의예입력하고자하는문자열의최대길이 : 40 문자열입력 : 인터넷미디어전공실습 II, Fighting! 입력된문자열출력 : 인터넷미디어전공실습 II, Fighting! 53/62 연습문제 2-3 2. 사용자로부터정수를입력받는다. -1이입력될때까지계속정수를입력받아서, 프로그램종료직전까지입력받은정수들을화면에출력하는프로그램을작성해보자. 그런데문제는사용자가정수를얼마나많이입력할지모른다는데있다. 그래서이문제를동적할당을통해서해결하고자한다. 일단은배열의길이를 5로하자. 그리고그이상입력이들어오면배열의길이를 3씩늘리기로하자 ( 그림 2.9 참조 ). 물론배열의길이를늘릴수없다. 보다큰길이의배열 ( 포인터 ) 을선언해서값을옮기는형식을취해야한다. 실행의예 number?: 1 number?: 2 number?: 3 number?: 4 number?: 5 number?: 6 number?: 7 number?: -1 The input numbers: 1, 2, 3, 4, 5, 6, 7 54/62 27

초기배열 1 차확장된배열 2 차확장된배열 1 2 3 4 5 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 9 10 11 그림 2-9: 동적으로 3 개씩확장되는배열 55/62 2-2 메모리동적할당 new 와 delete 연산자의기본적기능 malloc_free.cpp, new_delete.cpp int * val = new int; int * arr = new int[size];..... delete val; delete []arr;..... int * val = (int*)malloc(sizeof(int)); int * arr = (int*)malloc(sizeof(int)* size);..... free(val); free(arr);..... 56/62 28

2-2 메모리동적할당 /* new_delete.cpp */ #include <stdio.h> int size; printf(" 할당하고자하는배열의크기 : ); scanf( %d, &size); int* arr=new int[size]; // 배열의동적할당. for(int i=0; i<size; i++) arr[i]=i+10; for(int j=0; j<size; j++) printf( arr[%d]=%d n, j, arr[j]); delete []arr; // 할당된메모리소멸. /* Array_2.cpp */ #include <stdio.h> int main() int RowNum, ColNum; printf(" 원하는 2 차원배열을입력하세요? 예 3x4: 3 4 n"); scanf("%d %d", &RowNum, &ColNum); int *p2dary = new int [RowNum*ColNum]; // Print array addresses for(int row = 0 ; row < RowNum ; row++) for(int col = 0 ; col < ColNum ; col++) printf("%d ", &p2dary[row*colnum+col]); printf(" n"); delete [] p2dary; 57/62 2-2 메모리동적할당 NULL 포인터리턴하는 new 연산자 메모리할당실패시 NULL 포인터리턴! 새로운표준에관한내용은 " 예외처리 " 를통해서다시언급! NULL_new.cpp, Debug_new.cpp int* arr=new int[size]; if(arr==null) cout<<" 메모리할당실패 "<<endl; return -1; // 배열의동적할당 // 동적할당검사 // 프로그램종료 58/62 29

2-2 메모리동적할당 /* NULL_new.cpp */ #include <iostream> using std::cin; using std::cout; using std::endl; int size; cout<<" 할당하고자하는배열의크기 : "; cin>>size; int* arr=new int[size]; // 배열의동적할당. if(arr==null) cout<<" 메모리할당실패 "<<endl; return -1; // 프로그램종료. for(int i=0; i<size; i++) arr[i]=i+10; 동적메모리를할당할때메모리할당에대한실패를고려하여예외처리를함으로써좀더안정적인프로그램이된다. new 와 delete 는 malloc 과 free 함수로는할수없는기능을지닌다. -> 객체를동적으로생성하는기능 for(int j=0; j<size; j++) cout<<"arr["<<j<<"]= "<<arr[j]<<endl; delete []arr; // 할당된메모리소멸. 59/62 /* Debug_new.cpp */ #include <iostream> //#define DEBUG 1; #define DEBUG 0; using std::cin; using std::cout; using std::endl; int size; cout<<" 할당하고자하는배열의크기 : "; cin>>size; int* arr=new int[size]; // 배열의동적할당. #if DEBUG==1 cout<<" 디버그모드입니다 "<<endl; if(arr==null) cout<<" 메모리할당실패 "<<endl; return -1; // 프로그램종료. #endif for(int i=0; i<size; i++) arr[i]=i+10; for(int j=0; j<size; j++) cout<<"arr["<<j<<"]= "<<arr[j]<<endl; delete []arr; // 할당된메모리소멸. 메모리가제대로할당이이뤄졌는지를검사하는코드가 #if ~ #endif 문에의해서조건부컴파일을구성하고있다. 참고 ) 조건부컴파일이란컴파일러에게 이러이러하게컴파일해라 라고주문을하는것이다. 형식은다음과같다. -------------------------------------- #if CONDITION 1 expression1 #elif CONDITION 2 expression2 #else expression3 #endif -------------------------------------- 60/62 30

실습문제 힙 (Heap) 메모리에임의의외부파일에저장되어있는 2차원배열데이터를저장할수있는동적메모리를생성하고, 최소값과최대 값그리고각각의행의평균을계산하는프로그램을작성해보자. 2차원데이터는파일로부터읽는다. 처음두개의요소들은 배열의행과열의수를나타낸다. 파일데이터는아래와같다. 아래의 2차원배열은 12 x 8 배열이다. ------------------------------------ 12 8 838 758 113 515 51 627 10 419 212 86 749 767 84 60 225 543 89 183 137 566 966 978 495 311 367 54 31 145 882 736 524 505 394 102 851 67 754 653 561 96 628 188 85 143 967 406 165 403 562 834 353 920 444 803 962 318 422 327 457 945 479 983 751 894 670 259 248 757 629 306 606 990 738 516 414 262 116 825 181 134 343 22 233 536 760 979 71 201 336 61 160 5 729 644 475 993 -------------------------------------- 1. 문제에서주어진 2차원데이터배열을 ( 배열의행과열정보도같이 ) 메모장등의텍스트편집기를이용하여임의의이름으로파일을저장 ( 예 test.txt) 하고, File 입출력함수를통하여 test.txt에저장되어있는배열정보와데이터를정확하게읽고출력해보는프로그램을작성한다. ( 동적으로배열을할당시 2차원배열을 1차원배열로할당해도상관없음 ) 2. 각행의평균과전체데이터의최소값, 최대값을계산하고, 출력하는프로그램을추가하여프로그램을완성한다. 61/62 질문 & 답변 Thank You! 수고하셨습니다. 62/62 31