C 11장. 포인터의 활용 #include <stdio.h> int main(void) { int num;

Slides:



Advertisements
Similar presentations
제6장 조건문.
Advertisements

슬라이드 1~21까지는 각자 복습! 슬라이드 22부터는 수업시간에 복습
배열, 포인터 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express.
쉽게 풀어쓴 C언어 Express 제13장 구조체 C Express Slide 1 (of 25)
쉽게 풀어쓴 C언어 Express 제8장 함수 C Express.
쉽게 풀어쓴 C언어 Express 제8장 함수 C Express.
구조체 활용 구조체 활용.
쉽게 풀어쓴 C언어 Express 제13장 구조체 C Express.
C 6장. 함수 #include <stdio.h> int main(void) { int num;
쉽게 풀어쓴 C언어 Express 제8장 함수 C Express Slide 1 (of 26)
C 10장. 함수의 활용 #include <stdio.h> int main(void) { int num;
쉽게 풀어쓴 C언어 Express 제18장 입출력과 라이브러리 함수 C Express.
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
제5장 제어명령
C언어: 배열 (Arrays).
6장. printf와 scanf 함수에 대한 고찰
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 14. 포인터와 함수에 대한 이해.
연산자 대입 연산자 산술 연산자 관계 연산자 논리 연산자 비트 연산자 콤마 연산자 축약 연산자 sizeof 연산자
10장 메모리 관리.
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express.
동적메모리와 연결리스트 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 02. 프로그램의 기본구성.
C 9장. 구조체 #include <stdio.h> int main(void) { int num;
C 7장. 배열과 문자열 #include <stdio.h> int main(void) { int num;
컴퓨터 프로그래밍 기초 - 2nd : scanf(), printf() 와 연산자 -
쉽게 풀어쓴 C언어 Express 제3장 C프로그램 구성요소 C Express.
7장 배열 배열의 정의 배열의 초기화 1차원 배열 2차원 및 다차원 배열 문자 배열 배열과 구조.
10장 포인터와 문자열 포인터 기본 배열과 포인터 매개변수 전달방법 포인터와 문자열.
쉽게 풀어쓴 C언어 Express 제14장 포인터 활용 C Express.
Chapter 06. 선택문.
12장 파일처리와 매크로 파일 입출력 함수 문자 입출력 함수 라인 입출력 함수 불록 입출력 함수 매크로.
쉽게 풀어쓴 C언어 Express 제10장 배열 C Express.
6장 배열.
프로그래밍2 및 실습 C언어 기반의 C++ 2.
쉽게 풀어쓴 C언어 Express 제7장 반복문 C Express.
C 4장. 연산자 #include <stdio.h> int main(void) { int num;
2장 표준 입출력 표준 입출력 함수의 종류 형식화된 입출력 문자 입출력 문자열 입출력.
개정판 누구나 즐기는 C언어 콘서트 제6장 반복문 출처: pixabay.
자전거를 배우려면 안장에 올라가 페달을 밟아라.
컴퓨터 프로그래밍 기초 - 4th : 수식과 연산자 -
제어문 & 반복문 C스터디 2주차.
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 09. C언어의 핵심! 함수!
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
게임프로그래밍 I - 1차원 배열 - 공주대학교 게임디자인학과 박 찬 교수 2011년 4월 25일.
Chapter 11. 배열과 포인터.
실습과제 1(조건문, ) 표준입력으로 수축기 혈압을 입력 받아 그에 따른 적당한 표현을 화면에 출력하는 프로그램을 if-else 문을 이용하여 작성.
Fflush 사용이유 및 방법 [이유] 키보드에서 입력된 내용은 입력버퍼에 저장되었다가 Enter 키가 들어오면 프로그램으로 전달됨 이 때 입력버퍼에 있는 Enter 키도 프로그램으로 전달됨 그러므로 아래와 같은 프로그램에서 문자 하나를 입력해도 Enter키도 입력된 것으로.
#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 문 기타 제어문.
-Part1- 제7장 반복문이란 무엇인가.
18장. 다차원 배열 그리고 포인터.
-Part1- 제8장 조건문이란 무엇인가 (교재 199페이지 ~ 224페이지)
쉽게 풀어쓴 C언어 Express 제6장 조건문 C Express Slide 1 (of 28)
쉽게 풀어쓴 C언어 Express 제6장 조건문 C Express.
반복문의 기능 반복문 반복문 특정 영역을 특정 조건이 만족하는 동안에 반복 실행하기 위한 문장 while문
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
어서와 C언어는 처음이지 제16장.
개정판 누구나 즐기는 C언어 콘서트 제10장 문자열 출처: pixabay.
C 13장. 입출력 라이브러리 #include <stdio.h> int main(void) { int num;
어서와 C언어는 처음이지 제23장.
개정판 누구나 즐기는 C언어 콘서트 제11장 구조체, 공용체, 열거형 출처: pixabay.
C 4장. 연산자 #include <stdio.h> int main(void) { int num;
Chapter 09. 배열.
어서와 C언어는 처음이지 제22장.
배열, 포인터, 함수 Review & 과제 1, 2.
Presentation transcript:

C 11장. 포인터의 활용 #include <stdio.h> int main(void) { int num; printf(“Please enter an integer: "); scanf("%d", &num); if ( num < 0 ) printf("Is negative.\n"); printf("num = %d\n", num); return 0; }

학습목표 ■ 포인터를 사용하는 다양한 방법에 대하여 알아본다. ■ 포인터 배열을 선언하고 사용하는 방법을 알아본다. ■ 배열에 대한 포인터를 선언하고 사용하는 방법을 알아본다. ■ 함수에 대한 포인터를 선언하고 사용하는 방법을 알아본다. ■ 동적 메모리가 무엇인지 알아보고, 동적 메모리를 할당하고 사용한 다음 해제하는 방법을 알아본다. 11장. 포인터의 활용

목차 11장. 포인터의 활용 포인터 배열 배열에 대한 포인터 함수에 대한 포인터 동적 메모리 포인터 배열의 기본 구조체 포인터 배열 배열에 대한 포인터 배열에 대한 포인터와 이차원 배열 배열 원소를 가리키는 포인터와 배열에 대한 포인터 함수에 대한 포인터 함수에 대한 포인터 변수 함수에 대한 포인터형 함수에 대한 포인터의 활용 동적 메모리 동적 메모리의 필요성 동적 메모리의 할당 및 해제 동적 메모리의 활용 동적 메모리 관련 함수 11장. 포인터의 활용

포인터의 활용 포인터 배열의 기본 포인터 배열의 선언 주소를 저장하는 배열 11장. 포인터의 활용

포인터 배열의 사용(1/4) 포인터의 활용 포인터 배열의 각 원소로 변수의 주소를 저장한다. 포인터 배열의 기본 포인터 배열의 사용(1/4) 포인터 배열의 각 원소로 변수의 주소를 저장한다. 배열의 각 원소가 포인터형이므로, 원소가 가리키는 변수에 접근하려면 배열의 원소 앞에 간접 참조 연산자 *를 사용해야 한다. 11장. 포인터의 활용

포인터의 활용 포인터 배열의 기본 포인터 배열의 사용(2/4) 11장. 포인터의 활용

int 변수를 가리키는 포인터 배열의 사용 예 포인터의 활용 포인터 배열의 기본 11장. 포인터의 활용 01: /* Ex11_01.c */ 02: #include <stdio.h> 03: 04: int main(void) 05: { 06: int a=10, b=20, c=30, d=40, e=50; 07: int* arr[5] = {&a, &b, &c, &d, &e}; 08: int i; 09: 10: for( i = 0 ; i < 5 ; i++ ) 11: printf("%d ", *arr[i]); 12: printf("\n"); 13: 14: return 0; 15: } 포인터 배열의 선언 및 초기화 포인터 배열의 사용 11장. 포인터의 활용

포인터 배열의 사용(3/4) 포인터의 활용 포인터 배열의 각 원소에 배열의 시작 주소를 저장할 수도 있다. 포인터 배열의 기본 포인터 배열의 사용(3/4) 포인터 배열의 각 원소에 배열의 시작 주소를 저장할 수도 있다. arr[i]가 int 배열의 시작 주소로 초기화되었을 때, arr[i]가 가리키는 배열의 원소에 접근하려면 arr[i][j]라고 쓰면 된다. 11장. 포인터의 활용

포인터의 활용 포인터 배열의 기본 포인터 배열의 사용(4/4) 배열의 시작 주소로 초기화된 포인터 배열 11장. 포인터의 활용

int 배열의 원소를 가리키는 포인터 배열의 사용 예 포인터의 활용 포인터 배열의 기본 int 배열의 원소를 가리키는 포인터 배열의 사용 예 01: /* Ex11_02.c */ 02: #include <stdio.h> 03: 04: int main(void) 05: { 06: int x[3] = {1, 2, 3}; 07: int y[3] = {4, 5, 6}; 08: int z[3] = {7, 8, 9}; 09: int* arr[3] = {x, y, z}; 10: int i, j; 11: 12: for( i = 0 ; i < 3 ; i++ ) 13: { 14: for( j = 0 ; j < 3 ; j++) 15: printf("%d ", arr[i][j]); 16: printf("\n"); 17: } 18: 19: return 0; 20: } 포인터 배열의 선언 및 초기화 포인터 배열의 사용 11장. 포인터의 활용

구조체 포인터 배열의 필요성 포인터의 활용 구조체 배열은 메모리를 많이 사용하므로 비효율적이다. 구조체 포인터 배열을 이용하면 구조체는 동적 메모리에 할당하고 그 주소만 포인터 배열에 넣어두고 사용할 수 있다. 구조체 배열은 메모리를 많이 사용하므로 비효율적이다. 구조체 포인터 배열을 준비하고 구조체 변수를 필요할 때 메모리에 할당하고 그 주소만 저장한다. 11장. 포인터의 활용

포인터의 활용 구조체 포인터 배열 구조체 포인터 배열의 메모리 구조 11장. 포인터의 활용

구조체 포인터 배열의 사용 예(1/2) 포인터의 활용 구조체 포인터 배열 11장. 포인터의 활용 01: /* Ex11_03.c */ 02: #include <stdio.h> 03: #include <string.h> 04: 05: typedef struct product { 06: char name[20]; 07: int price; 08: int stock; 09: } PRODUCT; 10: 11: int main(void) 12: { 13: PRODUCT prd1 = { "A4용지", 5000, 50 }; 14: PRODUCT prd2 = { "충전기", 10000, 3 }; 15: PRODUCT prd3 = { "이어폰", 25000, 10 }; 16: PRODUCT* prd[] = { &prd1, &prd2, &prd3 }; 17: 구조체 포인터 배열의 선언 및 초기화 11장. 포인터의 활용

구조체 포인터 배열의 사용 예(2/2) 포인터의 활용 구조체 포인터 배열 11장. 포인터의 활용 18: int count = sizeof(prd) / sizeof(prd[0]); 19: int i; 20: 21: printf("상 품 명 가 격 재 고 량\n"); 22: for( i = 0 ; i < count ; i++ ) 23: { 24: printf("%-20s %8d %10d", 25: prd[i]->name, prd[i]->price, prd[i]->stock); 26: if( prd[i]->stock < 10 ) 27: printf(" ==> 주문 필요!!!\n"); 28: else 29: printf("\n"); 30: } 31: 32: return 0; 33: } 구조체 포인터 배열의 사용 11장. 포인터의 활용

배열에 대한 포인터 배열에 대한 포인터 배열에 대한 포인터의 선언 배열 전체를 가리키는 포인터 11장. 포인터의 활용

배열에 대한 포인터의 사용(1/4) 배열에 대한 포인터 배열에 대한 포인터에는 배열 전체의 주소를 저장한다. 배열 전체의 주소를 구하려면 배열 이름 앞에 & 연산자를 지정해야 한다 & 연산자 없이 배열의 이름만 사용하면 배열의 첫 번째 원소(arr[0])의 주소를 의미한다. 배열에 대한 포인터에는 크기가 같은 배열의 주소만 저장할 수 있다. 11장. 포인터의 활용

배열에 대한 포인터 배열에 대한 포인터 배열에 대한 포인터의 사용(2/4) 11장. 포인터의 활용

배열에 대한 포인터의 사용(3/4) 배열에 대한 포인터 p는 배열 전체의 주소이고, *p는 p가 가리키는 배열이 된다. *p는 배열 이름처럼 사용할 수 있으므로, p가 가리키는 배열의 i번째 원소에 접근하려면 (*p)[i]를 사용한다. *p는 p[0]이므로, (*p)[i]는 p[0][i]와 같다. 11장. 포인터의 활용

*p와 p[0] 배열에 대한 포인터 p가 포인터 변수일 때 *p와 p[0]은 항상 같다. int 변수는 크기가 1인 int 배열로 볼 수 있다. p가 배열에 대한 포인터일 때 (*p)[i]는 p[0][i]와 항상 같다. 11장. 포인터의 활용

배열에 대한 포인터의 사용(4/4) 배열에 대한 포인터 (*p)[i]와 *p[i]는 서로 의미가 다르므로 주의해야 한다. 11장. 포인터의 활용

배열에 대한 포인터의 사용 예 배열에 대한 포인터 배열에 대한 포인터 11장. 포인터의 활용 01: /* Ex11_04.c */ 02: #include <stdio.h> 03: 04: int main(void) 05: { 06: int arr[5] = {10, 20, 30, 40, 50}; 07: int (*p)[5] = &arr; 08: int i; 09: 10: for( i = 0 ; i < 5 ; i++ ) 11: printf("%d ", (*p)[i]); // p[0][i] 또는 *((*p)+i) 12: printf("\n"); 13: 14: return 0; 15: } 배열에 대한 포인터의 선언 및 초기화 배열에 대한 포인터로 배열의 원소 접근 11장. 포인터의 활용

배열에 대한 포인터와 이차원 배열(1/3) 배열에 대한 포인터 배열에 대한 포인터는 이차원 배열의 한 묶음을 가리키는 용도로 사용된다. 11장. 포인터의 활용

배열에 대한 포인터와 이차원 배열(2/3) 배열에 대한 포인터 배열에 대한 포인터를 &arr[0]으로 초기화하는 대신, 간단하게 arr로 초기화할 수 있다. 배열에 대한 포인터 p로 이차원 배열의 원소에 접근하려면 p가 마치 이차원 배열명인 것처럼 2개의 인덱스를 사용하면 된다. 11장. 포인터의 활용

배열에 대한 포인터와 이차원 배열(3/3) 배열에 대한 포인터 배열에 대한 포인터는 이차원 배열에 접근하기 위한 용도로 사용된다. 11장. 포인터의 활용

이차원 배열을 가리키는 배열에 대한 포인터(1/2) 배열에 대한 포인터와 이차원 배열 이차원 배열을 가리키는 배열에 대한 포인터(1/2) 01: /* Ex11_05.c */ 02: #include <stdio.h> 03: 04: int main(void) 05: { 06: int arr[3][5] = { 07: { 1, 2, 3, 4, 5}, 08: { 6, 7, 8, 9, 10}, 09: {11, 12, 13, 14, 15} 10: }; 11: 12: int (*p)[5] = arr; 13: 14: int i, j; 15: 이차원 배열의 선언 및 초기화 배열에 대한 포인터의 선언 및 초기화 11장. 포인터의 활용

이차원 배열을 가리키는 배열에 대한 포인터(2/2) 배열에 대한 포인터와 이차원 배열 이차원 배열을 가리키는 배열에 대한 포인터(2/2) 16: for( i = 0 ; i < 3 ; i++) 17: { 18: for( j = 0 ; j < 5 ; j++ ) 19: printf("%2d ", p[i][j]); 20: printf("\n"); 21: } 22: 23: return 0; 24: } 배열에 대한 포인터로 이차원 배열의 원소 접근 11장. 포인터의 활용

배열의 원소를 가리키는 포인터 배열에 대한 포인터 배열에 대한 포인터 배열 원소형에 대한 포인터로 선언 배열의 원소를 가리키는 포인터와 배열에 대한 포인터 배열의 원소를 가리키는 포인터 배열 원소형에 대한 포인터로 선언 일차원 배열의 시작 주소로 초기화 배열에 대한 포인터 이차원 배열의 제2크기와 같게 배열의 크기를 지정해서 선언 이차원 배열의 시작 주소로 초기화 11장. 포인터의 활용

배열의 원소를 가리키는 포인터와 배열에 대한 포인터의 구분 배열에 대한 포인터를 증가시키면 이차원 배열의 제2크기만큼씩 포인터의 주소가 증가된다. 11장. 포인터의 활용

배열의 원소를 가리키는 포인터와 배열에 대한 포인터 비교 01: /* Ex11_06.c */ 02: #include <stdio. 03: 04: int main(void) 05: { 06: int x[5]; 07: int *p1 = x; 08: 09: int y[2][3]; 10: int (*p2)[3] = y; 11: 12: printf("p1 = %p, p2 = %p\n", p1, p2); 13: 14: p1++; 15: p2++; 16: 17: printf("p1 = %p, p2 = %p\n", p1, p2); 18: 19: return 0; 20: } 배열의 원소를 가리키는 포인터의 선언 및 초기화 int*는 4바이트씩 증가하지만 int(*)[3]는 12바이트씩 증가한다. 배열에 대한 포인터의 선언 및 초기화 11장. 포인터의 활용

배열의 원소를 가리키는 포인터 vs. 배열에 대한 포인터 배열의 원소를 가리키는 포인터와 배열에 대한 포인터 배열의 원소를 가리키는 포인터 vs. 배열에 대한 포인터 배열의 원소를 가리키는 포인터는 일차원 배열의 원소에 접근할 때 사용되고, 배열에 대한 포인터는 이차원 배열의 원소에 접근할 때 사용된다. 11장. 포인터의 활용

함수에 대한 포인터 함수에 대한 포인터 함수의 주소를 저장하는 포인터 함수도 컴파일 및 링크 후에 메모리의 특정 번지에 할당된다. 실행 파일은 크게 코드 영역와 데이터 영역으로 나누어진다. 변수들은 데이터 영역에 할당되고, 함수들은 코드 영역에 할당된다. 11장. 포인터의 활용

함수에 대한 포인터 변수의 선언 함수에 대한 포인터 함수에 대한 포인터 변수가 가리킬 함수의 원형이 필요하다. 함수에 대한 포인터가 아직 가리키는 함수가 없으면 널 포인터로 초기화한다. 11장. 포인터의 활용

함수의 주소 구하기 함수에 대한 포인터 함수의 주소를 구할 때는 ( ) 없이 함수명 앞에 & 연산자를 써준다. 함수에 대한 포인터 변수 함수의 주소 구하기 함수의 주소를 구할 때는 ( ) 없이 함수명 앞에 & 연산자를 써준다. & 없이 함수명만 사용해도 된다. 11장. 포인터의 활용

함수에 대한 포인터로 함수 호출 함수에 대한 포인터 간접 참조 연산자를 이용해서 함수를 호출한다. 함수에 대한 포인터 변수 함수에 대한 포인터로 함수 호출 간접 참조 연산자를 이용해서 함수를 호출한다. 함수에 대한 포인터 변수가 함수명인 것처럼 사용할 수도 있다. 11장. 포인터의 활용

함수에 대한 포인터 사용 예(1/2) 함수에 대한 포인터 함수에 대한 포인터 변수 11장. 포인터의 활용 01: /* Ex11_07.c */ 02: #include <stdio.h> 03: 04: int GetFactorial(int n); 05: double Add(double x, double y); 06: 07: int main(void) 08: { 09: int (*pFunc)(int n) = &GetFactorial; 10: double (*pf)(double, double) = Add; 11: int num; 12: 13: printf("정수를 입력하세요 : "); 14: scanf("%d", &num); 15: printf("%d ! = %d\n", num, (*pFunc)(num)); 16: 17: printf("0.5 + 1.3 = %f\n", pf(0.5, 1.3)); 18: 19: return 0; 20: } 함수에 대한 포인터의 선언 및 초기화 함수에 대한 포인터로 함수 호출 11장. 포인터의 활용

함수에 대한 포인터 사용 예(2/2) 함수에 대한 포인터 함수에 대한 포인터 변수 11장. 포인터의 활용 22: int GetFactorial(int n) 23: { 24: int fact; 25: int i; 26: 27: for( i = 1, fact = 1 ; i <= n ; i++ ) 28: fact *= i; 29: 30: return fact; 31: } 32: 33: double Add(double x, double y) 34: { 35: return x + y; 36: } 11장. 포인터의 활용

함수에 대한 포인터 함수에 대한 포인터형 함수에 대한 포인터형의 정의 11장. 포인터의 활용

함수에 대한 포인터형의 사용 함수에 대한 포인터 함수에 대한 포인터형도 typedef로 정의된 데이터형이다. 함수에 대한 포인터형으로 선언된 변수는 함수에 대한 포인터 변수가 된다. 함수에 대한 포인터 변수를 직접 선언하는 것보다 함수에 대한 포인터형을 정의하는 것이 사용하기 간편하다. 11장. 포인터의 활용

퀵 정렬(1/2) 함수에 대한 포인터 정렬할 배열 중에서 키(key)을 선택한다. 함수에 대한 포인터의 활용 퀵 정렬(1/2) 정렬할 배열 중에서 키(key)을 선택한다. 정렬할 배열의 원소들을 키보다 작은 값과 키보다 큰 값의 두 그룹으로 나눈다. 두 그룹에 대해서 각각 다시 퀵 정렬을 수행한다. 그룹 내에 값이 하나만 남을 때까지 계속 이 작업을 반복한다. 11장. 포인터의 활용

함수에 대한 포인터 함수에 대한 포인터의 활용 퀵 정렬(2/2) 11장. 포인터의 활용

표준 C 라이브러리의 qsort 함수(1/3) 함수에 대한 포인터 함수에 대한 포인터의 활용 표준 C 라이브러리의 qsort 함수(1/3) 함수명은 몰라도 함수의 주소만 있으면 함수를 호출할 수 있다. 11장. 포인터의 활용

표준 C 라이브러리의 qsort 함수(2/3) 함수에 대한 포인터 함수에 대한 포인터의 활용 표준 C 라이브러리의 qsort 함수(2/3) qsort 함수에서 호출될 비교 함수를 정의하고, 그 주소를 qsort 함수의 마지막 인자로 전달한다. 비교 함수의 원형 e1, e2 : qsort 함수에 인자로 전달된 배열 원소를 가리키는 포인터 e1, e2는 모두 void*형 사용 전에 배열의 원소를 가리키는 포인터형으로 형 변환 리턴 값 > 0 : e1이 가리키는 원소가 더 크다. 리턴 값 < 0 : e2가 가리키는 원소가 더 크다. 리턴 값 == 0 : e1이 가리키는 원소와 e2가 가리키는 원소의 값이 같다. 기본적인 qsort 함수는 오름차순으로 정렬한다. 내림차순으로 정렬하려면 비교 함수의 리턴 값이 반대가 되도록 정의한다. 11장. 포인터의 활용

표준 C 라이브러리의 qsort 함수(3/3) 함수에 대한 포인터 int 배열을 오름차순으로 정렬할 때 사용될 비교 함수 함수에 대한 포인터의 활용 표준 C 라이브러리의 qsort 함수(3/3) int 배열을 오름차순으로 정렬할 때 사용될 비교 함수 qsort 함수는 구조체 배열을 정렬할 때도 사용할 수 있다. 11장. 포인터의 활용

콜백 함수 함수에 대한 포인터 라이브러리에 의해서 호출되는 사용자 프로그램 내의 함수 함수에 대한 포인터의 활용 콜백 함수 라이브러리에 의해서 호출되는 사용자 프로그램 내의 함수 qsort에 의해서 호출되는 비교 함수도 일종의 콜백 함수이다. 라이브러리로 함수의 주소를 넘겨주고, 라이브러리는 함수에 대한 포인터로 콜백 함수를 호출한다. 11장. 포인터의 활용

qsort 함수의 사용(1/2) 함수에 대한 포인터 함수에 대한 포인터의 활용 11장. 포인터의 활용 01: /* Ex11_08.c */ 02: #include <stdio.h> 03: #include <stdlib.h> 04: 05: int Compare(const void *e1, const void *e2); 06: void PrintArray(const int* arr, int size); 07: 08: int main( ) 09: { 10: int x[10] = {34, 50, 5, 17, 82, 66, 73, 1, 48, 29}; 11: 12: printf("정렬 전 : "); 13: PrintArray(x, 10); 14: 15: qsort(x, 10, sizeof(int), Compare); 16: 17: printf("정렬 후 : "); 18: PrintArray(x, 10); 19: 20: return 0; 21: } qsort 함수 사용시 필요한 헤더 비교 함수의 선언 qsort 함수의 호출 11장. 포인터의 활용

qsort 함수의 사용(2/2) 함수에 대한 포인터 함수에 대한 포인터의 활용 11장. 포인터의 활용 22: 23: int Compare(const void *e1, const void *e2) 24: { 25: int *p1 = (int*) e1; 26: int *p2 = (int*) e2; 27: return (*p1 - *p2); // 오름차순 정렬 28: //return -(*p1 - *p2); // 내림차순 정렬 29: } 30: 31: void PrintArray(const int* arr, int size) 32: { 33: int i; 34: 35: for( i = 0 ; i < size ; i++ ) 36: printf("%d ", arr[i]); 37: printf("\n"); 38: } int 배열 정렬시 사용될 비교 함수 11장. 포인터의 활용

qsort 함수를 이용한 구조체 배열의 정렬(1/4) 함수에 대한 포인터 함수에 대한 포인터의 활용 qsort 함수를 이용한 구조체 배열의 정렬(1/4) 01: /* Ex11_09.c */ 02: #include <stdio.h> 03: #include <stdlib.h> 04: #include <string.h> 05: 06: typedef struct product { 07: char name[20]; 08: int price; 09: int stock; 10: } PRODUCT; 11: 12: int CompareByName(const void *e1, const void *e2); 13: int CompareByPrice(const void *e1, const void *e2); 14: void PrintProductsList(const PRODUCT *prd, int count); 15: 16: int main( ) 17: { 18: PRODUCT prd[5] = { 19: { "커피믹스", 15000, 30 }, 20: { "생수2L", 9500, 20 }, 21: { "A4용지", 3000, 5 }, 22: { "클리어파일", 1000, 15 }, 23: { "화장지", 12000, 9 } 24: }; 11장. 포인터의 활용

qsort 함수를 이용한 구조체 배열의 정렬(2/4) 함수에 대한 포인터 함수에 대한 포인터의 활용 qsort 함수를 이용한 구조체 배열의 정렬(2/4) 25: 26: printf("*** 정렬 전 ***\n"); 27: PrintProductsList(prd, 5); 28: 29: qsort(prd, 5, sizeof(PRODUCT), CompareByName); 30: printf("*** 이름 순 정렬 ***\n"); 31: PrintStudent(std, 5); 32: 33: qsort(std, 5, sizeof(STUDENT), CompareByAve); 34: printf("*** 가격 순 정렬 ***\n"); 35: PrintProductsList(prd, 5); 36: 37: return 0; 38: } 39: 40: int CompareByName(const void *e1, const void *e2) 41: { 42: const PRODUCT *p1 = (const PRODUCT*) e1; 43: const PRODUCT *p2 = (const PRODUCT*) e2; 44: return strcmp(p1->name, p2->name); 45: } 46: 이름 순 정렬 가격 순 정렬 상품명 순 정렬에 사용될 비교 함수 11장. 포인터의 활용

qsort 함수를 이용한 구조체 배열의 정렬(3/4) 함수에 대한 포인터 함수에 대한 포인터의 활용 qsort 함수를 이용한 구조체 배열의 정렬(3/4) 47: int CompareByPrice(const void *e1, const void *e2) 48: { 49: const PRODUCT *p1 = (const PRODUCT*) e1 50: const PRODUCT *p2 = (const PRODUCT*) e2; 51: return p1->price - p2->price; 52: } 53: 54: void PrintProductsList(const PRODUCT *prd, int count) 55: { 56: int i; 57: 58: printf("\n상 품 명 가 격 재 고 량\n"); 59: for( i = 0 ; i < count ; i++ ) 60: { 61: printf("%-20s %8d %10d\n", 62: prd[i].name, prd[i].price, prd[i].stock); 63: } 64: printf("\n"); 65: } 가격 순 정렬에 사용될 비교 함수 11장. 포인터의 활용

qsort 함수를 이용한 구조체 배열의 정렬(4/4) 함수에 대한 포인터 함수에 대한 포인터의 활용 qsort 함수를 이용한 구조체 배열의 정렬(4/4) 11장. 포인터의 활용

동적 메모리 정적 메모리 vs. 동적 메모리 11장. 포인터의 활용

동적 메모리가 필요한 경우 동적 메모리 배열의 크기를 미리 알 수 없을 때, 배열의 크기는 변수로 지정할 수 없다. 동적 메모리의 필요성 동적 메모리가 필요한 경우 배열의 크기를 미리 알 수 없을 때, 배열의 크기는 변수로 지정할 수 없다. 배열의 최대 크기를 가정해서 최대 크기만큼 배열을 할당할 수 있다. 동적 메모리를 사용하면 프로그래머가 원하는 만큼 메모리를 할당할 수 있으므로 메모리 낭비를 최소화할 수 있다. 동적 메모리를 사용하면 메모리의 할당과 해제시점을 프로그래머가 마음대로 선택할 수 있다. 동적 메모리는 메모리 사용에 있어서 프로그래머에게 최대한의 자유를 보장한다. 배열의 크기는 상수로만 지정할 수 있다. 메모리 낭비 발생 11장. 포인터의 활용

동적 메모리의 할당(1/2) 동적 메모리 malloc 함수의 원형 malloc 함수의 사용 예 동적 메모리의 할당 및 해제 동적 메모리의 할당(1/2) malloc 함수의 원형 size : 할당할 메모리의 바이트 크기 리턴 값 : 할당된 메모리의 주소(void*형)  특정 포인터형 변수에 저장 동적 메모리를 할당할 수 없으면 NULL 리턴 malloc 함수의 사용 예 11장. 포인터의 활용

동적 메모리 동적 메모리의 할당 및 해제 동적 메모리의 할당(2/2) 11장. 포인터의 활용

동적 메모리의 사용 동적 메모리 동적 메모리의 주소를 저장하는 포인터 변수는 배열의 원소를 가리키는 포인터처럼 사용한다. 동적 메모리의 할당 및 해제 동적 메모리의 사용 동적 메모리의 주소를 저장하는 포인터 변수는 배열의 원소를 가리키는 포인터처럼 사용한다. 11장. 포인터의 활용

동적 메모리의 해제 동적 메모리 free 함수의 원형 free 함수는 인자로 넘겨준 포인터가 가리키는 동적 메모리를 해제한다. 동적 메모리의 할당 및 해제 동적 메모리의 해제 free 함수의 원형 memblock : 해제될 메모리의 주소 free 함수는 인자로 넘겨준 포인터가 가리키는 동적 메모리를 해제한다. 동적 메모리를 해제한 다음에는 동적 메모리를 가리키던 포인터 변수에 NULL을 대입하는 것이 안전하다. 11장. 포인터의 활용

동적 메모리의 이용 예(1/2) 동적 메모리 동적 메모리의 할당 및 해제 11장. 포인터의 활용 01: /* Ex11_10.c */ 02: #include <stdio.h> 03: #include <stdlib.h> 04: 05: int main( ) 06: { 07: int size; 08: int *arr = NULL; 09: int sum = 0; 10: double average = 0.0; 11: int i; 12: 13: printf("몇 개의 정수를 입력하시겠습니까? : "); 14: scanf("%d", &size); 15: 16: arr = malloc(sizeof(int)*size); 17: if( arr == NULL ) 18: { 19: printf("동적 메모리 할당 실패\n"); 20: return -1; 21: } 메모리 관련 함수를 사용하기 위해 필요한 헤더 동적 메모리의 주소를 저장할 포인터 선언 동적 메모리의 할당 11장. 포인터의 활용

동적 메모리의 이용 예(2/2) 동적 메모리 동적 메모리의 할당 및 해제 11장. 포인터의 활용 22: 23: printf("%d개의 정수를 입력하세요 : ", size); 24: for( i = 0 ; i < size ; i++ ) 25: scanf("%d", &arr[i]); 26: 27: for( i = 0 ; i < size ; i++ ) 28: sum += arr[i]; 29: 30: average = (double)sum / (double)size; 31: 32: printf("합계 : %d, 평균 : %f\n", sum, average); 33: 34: free(arr); 35: arr = NULL; 36: 37: return 0; 38: } 동적 메모리의 사용 동적 메모리의 해제 11장. 포인터의 활용

동적 메모리의 사용 과정(1/2) 동적 메모리 먼저 동적 메모리의 주소를 저장할 포인터 변수를 선언한다. 동적 메모리의 할당 및 해제 동적 메모리의 사용 과정(1/2) 먼저 동적 메모리의 주소를 저장할 포인터 변수를 선언한다. 동적 메모리를 할당할 때는 malloc 함수를 사용한다. malloc 함수의 인자로는 할당할 메모리의 바이트 크기를 지정한다. 동적 메모리를 사용할 때는 배열의 원소를 가리키는 포인터처럼 사용한다. 즉, arr[i]처럼 인덱스를 이용한다. 11장. 포인터의 활용

동적 메모리 동적 메모리의 할당 및 해제 동적 메모리의 사용 과정(2/2) 동적 메모리는 사용이 끝나면 free 함수로 해제한다. 이때 더 이상 해제된 동적 메모리를 가리키지 않도록 포인터 변수를 NULL로 만든다. 11장. 포인터의 활용

동적 메모리와 구조체 포인터 배열(1/3) 동적 메모리 동적 메모리의 활용 동적 메모리와 구조체 포인터 배열(1/3) 프로그램 실행 중에 구조체를 동적 메모리에 할당하고, 그 주소만 포인터 배열에 저장하고 사용할 수 있다. 직사각형에 대한 정보를 저장할 구조체 RECT의 정의 직사각형이 몇 개나 필요한지 미리 알 수 없으므로 구조체 포인터 배열 선언 11장. 포인터의 활용

동적 메모리와 구조체 포인터 배열(2/3) 동적 메모리 동적 메모리의 활용 동적 메모리와 구조체 포인터 배열(2/3) RECT 구조체는 필요할 때마다 동적 메모리에 할당하고 그 주소만 포인터 배열의 원소로 저장한다. arr[i]는 구조체 포인터이므로 구조체의 멤버에 접근할 때 -> 연산자를 이용한다. 11장. 포인터의 활용

동적 메모리와 구조체 포인터 배열(3/3) 동적 메모리 동적 메모리의 활용 동적 메모리와 구조체 포인터 배열(3/3) 구조체 포인터 배열을 사용하면 꼭 필요한 만큼만 구조체를 동적 메모리에 할당해서 사용할 수 있다. 사용이 끝난 후에 배열의 원소가 가리키는 동적 메모리를 해제해야 한다. 11장. 포인터의 활용

동적 메모리에 할당된 구조체를 가리키는 포인터 배열(1/3) 동적 메모리의 활용 동적 메모리에 할당된 구조체를 가리키는 포인터 배열(1/3) 01: /* Ex11_11.c */ 02: #include <stdio.h> 03: #include <stdlib.h> 04: 05: typedef struct rect { 06: int x, y; 07: int width, height; 08: } RECT; 09: 10: int main(void) 11: { 12: RECT *arr[100] = {NULL}; 13: int count = 0; 14: int i; 15: 16: while(1) 17: { 18: char choice; 19: printf("직사각형을 만들겠습니까? (Y/N) : "); RECT 구조체의 정의 구조체 포인터 배열의 선언 11장. 포인터의 활용

동적 메모리에 할당된 구조체를 가리키는 포인터 배열(2/3) 동적 메모리의 활용 동적 메모리에 할당된 구조체를 가리키는 포인터 배열(2/3) 20: scanf("%c", &choice); 21: fflush(stdin); 22: if( toupper(choice) == 'N' ) 23: break; 24: 25: arr[count] = malloc(sizeof(RECT)); 26: arr[count]->x = rand( )%400; 27: arr[count]->y = rand( )%400; 28: arr[count]->width = rand( )%100; 29: arr[count]->height = rand( )%100; 30: count++; 31: } 32: printf("%d개의 직사각형이 만들어졌습니다.\n", count); 33: 34: for(i = 0 ; i < count ; i++) 35: { 36: printf("%d번째 직사각형 : (%3d,%3d) w=%3d, h=%3d\n", 37: i+1,arr[i]->x,arr[i]->y,arr[i]->width,arr[i]->height); 38: } 구조체에 대한 동적 메모리 할당 구조체 포인터 배열의 사용 11장. 포인터의 활용

동적 메모리에 할당된 구조체를 가리키는 포인터 배열(3/3) 동적 메모리의 활용 동적 메모리에 할당된 구조체를 가리키는 포인터 배열(3/3) 39: 40: for(i = 0 ; i < count ; i++) 41: { 42: free(arr[i]); 43: arr[i] = NULL; 44: } 45: 46: return 0; 47: } 동적 메모리의 해제 11장. 포인터의 활용

동적 메모리 동적 메모리 관련 함수 동적 메모리 관련 함수 11장. 포인터의 활용

포인터의 활용 학습정리 포인터 배열 : 주소를 저장하는 배열 int *arr[3]; 배열에 대한 포인터: 배열 전체를 가리키는 포인터 int (*p)[3]; 함수에 대한 포인터: 함수를 가리키는 포인터 int (*pf)(int); 함수에 대한 포인터 형: 함수를 가리키는 포인터 형 typedef int (*FUNCPTR)(int); 11장. 포인터의 활용

학습정리 동적 메모리 동적 메모리의 필요성 : 실행 중에 필요한 메모리의 크기를 결정하거나, 함수가 리턴해도 해제되지 않은 메모리가 필요할 때 동적 메모리를 사용한다. 동적 메모리의 할당 : malloc 함수를 사용한다. int *arr = malloc(sizeof(int) * size); 동적 메모리의 사용 : 동적 메모리를 가리키는 포인터를 배열 원소를 가리키는 포인터처럼 사용한다. 즉, 동적 메모리를 가리키는 포인터를 배열 이름인 것처럼 사용한다. for(i = 0 ; i < size ; i++) sum += arr[i]; 동적 메모리의 해제 : free 함수를 사용한다. free(arr); 11장. 포인터의 활용

11장. 포인터의 활용 수고하셨습니다. 질문 있습니까? NEXT Chapter 12장. 고급기능