560 likes | 783 Views
최신 C 프로그래밍 언어 문제해결에서 프로그래밍까지. 개정판. 8 장 : 포인터 도서출판 - 인터비젼. 8 장 포인터. 학습목표 1. 포인터의 개념을 이해한다 . 2. 배열과 포인터의 관계를 이해한다 . 3. 포인터를 이용한 주소 계산과 활용 방법을 이해한다 . 4. 포인터를 이용한 동적 메모리 할당과 사용법을 이해한다 . 5. 포인터 활용 연산자에 대해 이해한다. 목차. 8 장 포인터 예습시간 1. 포인터의 개념 [ 기초다지기 ] 포인터 개념 익히기
E N D
최신 C프로그래밍 언어문제해결에서 프로그래밍까지 개정판 8장 : 포인터 도서출판 - 인터비젼
8장 포인터 • 학습목표 • 1. 포인터의 개념을 이해한다. • 2. 배열과 포인터의 관계를 이해한다. • 3. 포인터를 이용한 주소 계산과 활용 방법을 이해한다. • 4. 포인터를 이용한 동적 메모리 할당과 사용법을 이해한다. • 5. 포인터 활용 연산자에 대해 이해한다.
목차 • 8장 포인터 • 예습시간 • 1. 포인터의 개념 • [기초다지기] 포인터 개념 익히기 • 2. 배열과 포인터 그리고 연산자 • [기초다지기] 배열과 포인터 관계 이해하기 • 3. 메모리 동적 할당 함수 • [기초다지기] 메모리와 동적 할당 함수 이해하기 • 실습시간 • 포인터와 관련 연산자 활용 • 동적 메모리 활용 • 연습시간 • 포인터 분석
포인터의 개념 예습시간 – 1 교시
포인터의 개념 • 학습 개요 • 포인터의 의미와 활용 방법을 다룬다. • 주소 관련 연산자를 이해한다. • 다중 포인터의 개념에 대해 이해한다.
포인터의 개념 • 포인터의 개요 • 데이터 값의 위치를 나타내는 메모리 주소를 저장하기 위해 사용되는 특별한 변수 • 일반변수 • 특정 공간의 메모리 주소에 할당되고 변수 이름을 통해 접근 • 포인터 • 특정 공간의 메모리 주소를 저장하는 변수 • 포인터 변수를 통해 메모리 주소의 조작이 가능
포인터의 개념 • 포인터 변수의 선언 • 포인터 변수를 사용하기 위해 먼저 선언되어야 한다. • 선언 방법 • [데이터 형] *[포인터변수명]; • 데이터 형 : 저장된 주소가 가리키는 공간에 저장된 데이터 형 • 포인터 변수명 : 주소를 저장할 공간의 이름 • 사용 예 : int *px; 포인터 변수의 크기는 4byte이다.
포인터의 개념 • 주소 관련 연산자 • 포인터 변수의 활용 • 어떻게 값이 저장된 변수의 주소를 얻어올 수 있는가? • 주소 연산자(&) • 변수의 주소 값을 얻어오는 연산자 • 어떻게 포인터 변수가 가리키고 있는 주소의 실제 값을 얻어올 수 있는가? • 간접 지정 연산자(*) • 포인터 변수가 가리키는 위치의 값을 얻어오는 연산자 • 포인터에서 사용되는 "*"의 의미 • 선언 시의 "*" : 변수가 포인터 변수라는 것을 알려준다. • 활용 시의 "*" : 간접 지정 연산자의 역할
포인터의 개념 • 포인터 변수 활용 예 • 01 #include <stdio.h> • 02 void main(){ • 03 char c = 'x'; // 일반 변수 선언과 초기화 • 04 char *cp; // 포인터 변수 선언 • 05 cp = &c; // 주소 연산자를 이용해 변수 c의 주소 cp에 할당 • 06 // 간접 지정연산자를 이용해 cp가 가리키는 데이터 값 출력 • 07 printf(" 포인터 주소 cp 가 가리키는 데이터 값 : %c \n", *cp); //간접지정 연산자 사용 • 08 } • 사용되는 메모리 구조
포인터의 개념 • 다중 포인터 • 포인터에 대한 포인터 • 포인터가 다른 포인터의 주소를 가리키는 구조 • 이론적으로 여러 개의 포인터들이 서로 연결될 수 있지만 주로 두 개의 포인터로 구성된 이중 포인터 형식이 많이 사용됨 • 이중 포인터에 대한 선언 • 형식 : [데이터 형] **[포인터 변수명]; 이중 포인터변수와 메모리 관계
포인터의 개념 • 이중 포인터의 활용 예 • 01 #include <stdio.h> • 02 void main(){ • 03 int x, *px, **ppx; • 04 x = 10; • 05 px = &x; • 06 ppx = &px; • 07 printf("x의 값 : %d \n", x); • 08 printf("px가 가리키는 값 : %d \n", *px); • 09 printf("ppx에 저장된 주소 값 : %x \n", *ppx); • 10 printf(ppx가 가리키는 주소가 가리키는 값 : %d \n", **ppx); • 11 } • x와 *px 그리고 **ppx의 관계 • 출력 결과 • x = ____________ *px = ____________ • *ppx = ____________ **ppx = ____________ 10 10 px의 주소 10
[기초다지기] 포인터 개념 익히기 • 1. 포인터 변수와 주소지정 연산자 이용하기 • 분석 • 문자형 변수 c나 정수형 변수 value의 주소는 & 연산자를 통해 얻음 • 변수의 주소값 • cp = &c와 ip = &value • cp와 ip는 변수의 형에 대한 포인터 변수로 char *cp 그리고 int *ip로 선언 • printf 함수에서 포인터 변수의 주소 출력 : %X(16진수 표기) • printf 함수에서 사용되는 *cp에서 * • 간접 지정 연산자로 cp주소가 가리키고 있는 값을 가져온다
[기초다지기] 포인터 개념 익히기 • 2. 이중 포인터 활용하기
[기초다지기] 포인터 개념 익히기 • 2. 이중 포인터 활용하기 • 분석 • 이중 포인터 • 포인터 변수에 대한 주소를 가진 변수 • 포인터에 대한 포인터로 인식 • 프로그램은 4개의 수 중 가장 큰 수를 포인터를 이용하여 얻어옴 • 일반변수 i,j,x,y, 포인터 변수 ip, xp, 이중 포인터 변수 ipp 선언 • 처리과정 • 첫 번째 scanf를 통해 두 수를 입력 받아 큰 값을 가진 변수의 주소를 ip에 할당 • 두 번째 scanf에서도 두개의 변수를 입력받고 큰 수를 가진 변수의 주소를 xp에 저장 • 그 다음 if문을 통해 ip가 가리키는 값(*ip)와 xp가 가리키는 값(*xp)를 비교하여 큰 값을 가리키고 있는 포인터 변수를 ipp에 저장 • 마지막으로 printf함수에서 두개의 간접지정 연산자(**ipp)를 통해 ipp가 가리키는 주소의 포인터 변수가 가리키는 값 출력
배열과 포인터 그리고 연산자 예습시간 – 2 교시
배열과 포인터 그리고 연산자 • 학습 개요 • 포인터와 배열의 연관관계에 대해 알아본다. • 포인터 조작을 위한 연산자들에 대해 알아본다. • 이차원 배열과 포인터의 관계를 이해한다. • 문자열 배열과 포인터의 관계를 이해한다. • 포인터 배열에 대해 이해한다.
배열과 포인터 그리고 연산자 • 배열과 포인터 • 배열과 포인터는 서로 밀접한 연관관계를 가지고 있기 때문에 필요에 따라 이들을 교환하여 사용할 수 있다. • 배열 • 동일한 유형의 데이터들이 기억장소에 순차적으로 저장된 형태 • 배열의 대표 명은 배열의 시작 주소 • 배열에 대한 포인터 변수 할당 예 • 01 int *pArray, array[5] = {1,2,3,4,5}; • 02 pArray = array; • 메모리 구조
배열과 포인터 그리고 연산자 • 포인터 조작 연산자 • 포인터의 사용목적 • 주소 조작을 보다 편리하기 사용하기 위해 • 포인터 조작 연산자 • 포인터 변수를 대상으로 수행되며 주소 값의 변화를 제공 • 주소에 대한 덧셈과 뺄셈 연산만이 사용 가능하다. • 포인터 값의 1 증가는 실제 데이터 타입의 크기만큼 증가가 이루어짐 • 연산자 종류와 사용형태 그리고 메모리와의 관계
배열과 포인터 그리고 연산자 • 포인터 조작 연산자 사용 예 • 01 #include <stdio.h> • 02 void main(){ • 03 static int array[5]={1,2,3,4,5}; • 04 int *pArray; • 05 int i; • 06 pArray = array; • 07 for(i=0;i<5;i++){ • 08 printf("array[i] = %d \n",*pArray); • 09 pArray = pArray + 1; • 10 } • 11 } 출력 결과 :_____________ 1 2 3 4 5 포인터 변수와 배열의 메모리 관계
배열과 포인터 그리고 연산자 • 이차원 배열과 포인터 • 이차원 배열은 행렬로 표현되며 포인터 변수를 통해 조작 가능 • 활용 예 • 01 #include <stdio.h> • 02 void main(){ • 03 static int data[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; • 04 int *p, i; • 05 p = data; • 06 // 첫 번째 행의 값 출력 • 07 printf("첫 번째 행의 값은 : "); • 08 for(i=0; i<4; i++){ • 09 printf("%5d",*p++); • 10 } • 11 //세 번째 행의 값 출력 • 12 printf("\n세 번째 행의 값은 : "); • 13 p = data[2]; • 14 for(i=0; i<4;i++){ • 15 printf("%5d",*p++); • 16 } • 17 printf("\n"); • 18 } 첫 번째 행의 값은 : 1 2 3 4 세 번째 행위 값은 : 9 10 11 12 출력결과 :
배열과 포인터 그리고 연산자 • 이차원 배열과 포인터 • 프로그램에 대한 메모리 구조 p = data; 일 경우 포인터 변수 p와 data의 관계 p == data == data[0] == &data[0][0] == 1940번지
배열과 포인터 그리고 연산자 • 문자열 배열과 포인터 • 문자열 배열 역시 포인터를 통해 조작 가능한다. • 사용 예> • 01 #include <stdio.h> • 02 void main(){ • 03 char greeting[] ="Hi everyone!"; • 04 char *cp; • 05 cp = greeting; • 06 printf("%s\n",cp); • 07 cp=cp+3; • 08 printf("%s\n",cp); • 09 } Hi everyone! everyone! 출력 결과 : 변수들의 메모리 관계
배열과 포인터 그리고 연산자 • 포인터 배열 • 포인터 변수를 배열로써 관리 • 포인터 변수들을 집단으로 관리하는 상황에서 자주 사용됨 • 문자열 배열 관리를 위해 주로 이용됨 • 문자열 배열의 사용 예 • static char menu[][8] = {"File", "Open", "Save As"}; • 메모리 구조 • 문제점 • 문자열 구성 요소 중 상대적으로 큰 문자열이 존재할 경우 메모리 낭비
배열과 포인터 그리고 연산자 • 포인터 배열 • 포인터 배열의 사용 예 • static char *pmenu[]={"File", "Open", "Save As"}; • 메모리 구조 • 문자열을 가리키는 주소를 저장하는 1차원 배열 • 각각의 배열 요소는 독립적인 공간을 가진 문자열 주소를 저장 • 문자열 배열에 비해 메모리 낭비를 줄인다.
[기초다지기] 배열과 포인터 관계 이해 • 1. 1차원 배열과 포인터관계
[기초다지기] 배열과 포인터 관계 이해 • 2. 이차원 배열과 포인터 활용
[기초다지기] 배열과 포인터 관계 이해 • 3. 포인터 배열에 대해 이해하자.
메모리 동적 할당 함수 예습시간 – 3 교시
메모리 동적 할당 함수 • 학습 개요 • 동적인 메모리 관리에 대해 이해한다. • 메모리의 동적 할당 관련 함수들에 대해 알아본다. • calloc 함수 • malloc 함수 • free 함수 • realloc 함수
메모리 동적 할당 함수 • 메모리 동적 할당 함수 개요 • 주 기억 장치 구조 • 정적인 데이터 정보 저장 공간 (Heap) • 전역 변수나 정적 변수 등의 저장 공간 • 프로그램 수행 시 항상 존재하는 변수 저장 • 임시 데이터 정보 저장 공간 (Stack) • 지역 변수 • 프로그램 수행 도중 임시적으로 발생되는 변수 저장 공간 • 메모리 동적 할당 • 실행도중 메모리 공간을 할당하여 사용 • 힙(Heap)영역을 이용한 메모리 할당 • 동적 메모리 할당 관련 함수 헤더파일 • 동적 메모리 관련 함수 정보 • #include <stdlib.h>
메모리 동적 할당 함수 • calloc 함수 • 배열을 저장할 크기의 기억 장소를 할당하고 할당된 주소를 리턴 한다. • 함수의 원형 • void *calloc(size_t num, size_t size); • size_t 타입 :unsigned int 타입을 재정의 • num : 생성할 배열의 수 • size : 요소의 크기 • 반환 결과 : 정상적일 경우 할당된 주소 비정상적인 경우 NULL
메모리 동적 할당 함수 • calloc 함수 활용 예 • 01 #include <stdio.h> • 02 #include <stdlib.h> // calloc 함수 사용 목적 • 03 void main(){ • 04 int *p; //포인터 변수 • 05 int *tp,i; //임시 포인터 와 변수 • 06 p = (int *)calloc(10,sizeof(int)); // 정수형 10개의 배열을 가진 공간 할당 후 주소 값 전달 • 07 if(p!=NULL){ // 정상적인 할당 여부 확인 • 08 tp = p; • 09 for(i=0;i<10;i++){ • 10 *tp++ = i; //tp가 가리키는 공간에 i 값 할당 후 주소 1증가(주소: tp + int 크기) • 11 } • 12 tp = p; • 13 for(i=0;i<10;i++){ • 14 printf("%5d",*tp++); • 15 } • 16 printf("\n"); • 17 } • 18 } // 할당된 포인터 주소는 타입 변환(int *) 후 p에 할당 출력 결과 : 0 1 2 3 4 5 6 7 8 9
메모리 동적 할당 함수 • malloc 함수 • 하나의 데이터 크기에 대한 기억장소 할당 • 함수의 원형 • void *mallic(size_t size); • size : 데이터의 크기 • 사용 예 • 01 #include <stdio.h> • 02 #include <stdlib.h> • 03 void main(){ • 04 double *p; //포인터 변수 • 05 p = (double *)malloc(sizeof(double)); // double 크기의 공간 확보 • 06 if(p!=NULL){ • 07 *p = 3.1415913; • 08 printf("p의 값 : %.4f \n",*p); • 09 } • 10 } 출력 결과 : 3.1416
메모리 동적 할당 함수 • calloc와 malloc 관계 • 둘 다 메모리의 공간을 할당하는 함수 • 인자의 형태가 다르다. • calloc 함수 : 배열형 할당 • malloc 함수 : 데이터형 할당 • 인자의 형태가 다르지만 메모리 공간 할당 행위는 동일하다. • malloc 함수를 이용해 calloc 함수와 동일한 공간을 할당 가능하다. • p1 = (int *) calloc(10,sizeof(int)); • p2 = (int *) malloc(sizeof(int)*10); • p1과 p2는 둘다 정수형 10개의 배열 공간을 할당하고 있다.
메모리 동적 할당 함수 • 기타 함수 • free 함수 • 할당된 메모리 공간 해제 함수 • 동적 메모리를 통해 할당된 기억공간은 더 이상 사용하지 않을 경우 반드시 그 메모리 공간을 해제하여 주어야 한다. • 기억 공간이 해제 후 다른 프로그램에서 이 공간을 사용할 수 있다. • 함수의 원형 • void free(void *ptr) • 이전 calloc나 malloc을 통해 할당받은 주소를 free 함수에 전달 • 사용 예 > • 01 ... • 02 int *p; • 03 p = (int *)malloc(sizeof(int)); • 04 if(p!=NULL){05 ... • 06 free(p); • 07 }
메모리 동적 할당 함수 • 기타 함수 • realloc 함수 • 이미 할당된 메모리 공간을 늘리거나 줄일 경우에 사용 • 기존에 존재하는 데이터는 보존 • 함수의 원형 • void *realloc(void *ptr, size_t size); • ptr : 이전에 할당된 메모리 주소 • size : 새롭게 할당할 메모리 크기 • 사용 예 • 01 char *cp; • 02 cp = (char *)malloc(10); • 03 strcpy(cp,"hi there"); • 04 cp = (char *)realloc(20); • 05 ...
[기초다지기] 메모리와 동적 할당 함수 • 1. calloc 함수 활용하기
[기초다지기] 메모리와 동적 할당 함수 • 2. malloc와 realloc 함수 활용
포인터와 관련 연산자 활용 실습시간 – 1 교시
포인터와 관련 연산자 활용 • 학습개요 • 배열과 포인터 관계를 이해한다. • 포인터를 이용한 배열의 데이터 조작 방법을 다룬다. • 성적 처리 프로그램 작성을 통한 포인터 이해
포인터와 관련 연산자 활용 • 성적 처리 프로그램 • 문제 정의 • 성적 처리 프로그램을 작성하고자 한다. 학생은 5명이고 과목은 국어, 영어, 수학인 3과목을 대상으로 한다. 학생 별 총점이 필요하고 각 과목당 총점과 평균을 계산할 필요가 있다. 성적의 값은 정수 값으로 입력되어지고 평균은 실수(double)값으로 처리한다. 이 프로그램을 포인터를 이용하여 작성하시오. • 입/출력 조건 • 입력 조건 • 5명의 학생에 대한 국어, 영어, 수학 점수 • 100점을 기준으로 입력한다. • 출력 조건 • 각 개인별 성적 리스트와 총점 • 과목별 총점과 평균 데이터
포인터와 관련 연산자 활용 • 성적 테이블 출력 형식 ****************************************** 번호 국어 영어 수학 총점 ****************************************** 1 XXX XXX XXX XXX 2 XXX XXX XXX XXX 3 XXX XXX XXX XXX 4 XXX XXX XXX XXX 5 XXX XXX XXX XXX ****************************************** 과목총점 XXX XXX XXX XXX ****************************************** 과목평균 X.XX X.XX X.XX X.XX ****************************************** • 실행 후 결과 형식
포인터와 관련 연산자 활용 • 관련 함수 및 식 • (1) 성적은 scores[6][5] 크기의 배열로 관리한다. • (2) 평균데이터는 aves[5] 크기의 배열로 관리한다. • (3) 총점은 개인별 국어, 영어, 수학 점수의 합이다. • (4) 과목총점은 과목당 학생들이 취득한 점수의 합이다. • (5) 과목평균은 과목총점은 /학생수로 나눈 값이다. • (6) 배열에 데이터 값 처리와 할당을 위해 포인터변수를 활용한다. • 알고리즘 (또는 플로우차트) • 1. 5명의 학생에 대한 국어, 영어, 수학 점수 입력 • 2. 데이터 값 처리 • 2.1. 개인별 총점 처리 • 2.2 과목별 총점 처리 • 2.3 과별별 평균 처리 • 3. 처리정보 출력 • 3.1 타이틀 출력 • 3.2 개인별 정보 출력(개인 총점 포함) • 3.3 과목총점 출력 • 3.4 과목평균 출력
포인터와 관련 연산자 활용 • 프로그램 작성 • 1 단계 • 216페이지의 프로그램을 알고리즘을 참조하여 빈 곳을 채워 넣고 프로그램을 완성한 후 score.c 이름으로 저장하자. • 2 단계 • 프로그램이 정상적으로 작동하는지를 확인 한 후 다음 입력에 대한 출력 결과를 작성하자. ①. ps+1,ps+2,ps+3 ②. scores[i] ③. *(ps+j) ④. *(++pa) = (*(++ps))/5.0 ⑤. titles[i] ⑥. *ps++
포인터와 관련 연산자 활용 • 1. 디버깅 환경에서 다음 포인터 변수의 주소를 확인하자. • 42라인의 ps가 저장하고 있는 주소 값 : ____________________ • 43라인의 pa가 저장하고 있는 주소 값 : ____________________ • 2. 입력 결과에 대한 출력 값 확인
동적 메모리 활용 실습시간 – 2 교시
동적 메모리 활용 • 학습개요 • 메모리 동적 할당 방법을 익힌다. • 동적 할당 함수를 이용한 메모리 활용 기법을 다룬다. • 1교시의 정적 배열 구조를 동적 할당 방법으로 변환한다. • 정렬 문제를 다룬다.
동적 메모리 활용 • 동적 할당을 이용한 성적처리 프로그램 • 문제 정의 • 실습 1에서 포인터를 이용한 성적 처리 프로그램을 작성해 보았다. 그러나 학생들의 수가 변화되는 상황에서는 항상 프로그램을 수정하여야 한다. 그 결과 학생 수의 변화에 대응할 수 있는 프로그램 작성이 요구사항에 추가되었다. 또한 처리 결과를 학생들의 총점을 이용해 내림차순으로 정렬하여 출력하고 싶다. 이러한 조건을 만족하는 프로그램을 작성하여라. 이 프로그램은 동적 메모리 할당과 포인터를 이용해 구현하여라. • 입/출력 조건 • 입력 조건 • 입력하고자 하는 학생의 수 • 학생 수에 대한 국어, 영어, 수학 점수 , 100점을 기준으로 입력한다. • 출력 조건 • 각 개인별 성적 리스트와 총점 • 과목별 총점과 평균 데이터 , 총점으로 정렬된 성적 테이블
동적 메모리 활용 • 출력 형식 ****************************************** 번호 국어 영어 수학 총점 ****************************************** 3 XXX XXX XXX 290 1 XXX XXX XXX 270 4 XXX XXX XXX XXX 2 XXX XXX XXX 196 ****************************************** 과목총점 XXX XXX XXX XXX ****************************************** 과목평균 X.XX X.XX X.XX X.XX ****************************************** • 입/출력 화면
동적 메모리 활용 • 관련 함수 및 식 • (1) 동적 메모리 관련 함수는 stdlib.h 파일에 정의되어 있다. • (2) 동적 메모리 할당 함수 : calloc(), malloc() • (3) 동적 메모리 해제 함수 : free() • (4) 성적은 pRow 라는 포인터로 관리한다. • (5) 과목별 총점은 pTot로 평균은 pAves 포인터로 관리한다. • (6) 총점은 개인별 국어, 영어, 수학 점수의 합이다. • (7) 과목총점은 과목당 학생들이 취득한 점수의 합이다. • (8) 과목평균은 과목총점은 /학생수로 나눈 값이다. • (9) 정렬은 개인별 총점을 기준으로 내림차순 정렬한다. • (선택 정렬 알고리즘 사용)