Download presentation
Presentation is loading. Please wait.
1
C 언어 (STS ) 10. Pointer Applications
2
Arrays and pointers 배열 이름은 첫 번째 요소의 주소 값을 나타낸다.
int a[5]; 와 같이 선언되었을 때 메모리의 상황은 다음과 같다. 배열 이름인 a는 배열의 첫 번째 원소인 a[0]을 가리키고 있다. 즉, a 는 &a[0] 값을 가지고 있다.
3
Arrays and pointers 다음은 a와 &a[0]이 같은 값을 가짐을 보이는 예제이다.
a가 a[0]의 주소값을 가지고 있기 때문에, 당연히 a[0]은 *a를 통해서도 접근할 수 있다. *a와 a[0] 모두 배열 a의 첫번째 원소를 가리킨다.
4
Arrays and pointers 배열 이름 a는 주소값을 갖는 포인터이다.
주소값을 다른 포인터 변수에 할당할 수도 있다. 단, 배열 이름 a는 배열의 시작 주소를 갖도록 고정되어 있기 때문에 a의 값을 변경할 수는 없다. 배열의 시작주소값을 포인터 변수 p 에 할당
5
포인터변수 p도 a와 같은 값을 갖는다. 즉, 배열의 시작 주소를 갖는다.
Arrays and pointers 포인터 변수가 배열을 참조하도록 함으로써 포인터 변수를 배열처럼 사용하는 것도 가능하다. a p a[0] 1 p[0] a[1] 2 p[1] a[2] 3 p[2] a[3] 4 p[3] a[4] 5 p[4] 포인터변수 p도 a와 같은 값을 갖는다. 즉, 배열의 시작 주소를 갖는다. a[i]와 p[i]는 같은 결과를 갖는다. 결국 p를 이용해서도 배열에 접근할 수 있음을 알 수 있다.
6
Arrays and pointers 배열의 중간 부분의 주소를 pointer 변수에 할당할 수도 있다.
이 경우 같은 메모리 공간을 access하기 위해서는 서로 다른 index를 사용해야 한다. p[-1] = p[0] = p[1] = p[2] = p[3] =
7
Pointer arithmetic and arrays
Pointers and One-Dimensional Arrays p가 특정 데이터타입에 대한 포인터 변수일 때 수식 p + 1은 해당 데이터타입의 다음 변수를 나타낸다. 포인터 연산 p + 1에서 더해지는 값 1은 현재 포인터의 data type의 size만큼을 더하는 것이다. 다른 타입을 갖는 배열에 대한 포인터 연산의 결과 포인터 + 정수값 포인터 + (정수값 * 포인터가 가리키는 자료형의 크기)
8
Pointer arithmetic and arrays
(-) 연산은 (+) 연산과 마찬가지로 해당되는 type의 하나 이전의 element를 가리키게 된다. 역참조 연산자를 이용한 사용도 가능하다. a+1은 &a[1]와 같으므로 *(a+1)은 a[1]와 같다.
9
Pointer arithmetic and arrays
배열의 요소를 참조하는 여러가지 방법 2 4 6 8 22 p a a[1] a[2] a[3] a[4] a[0] *(a+0) *(a+1) *(a+2) *(a+3) *(a+4) *(p+0) *(p+1) *(p+2) *(p+3) *(p+4) p[0] p[1] p[2] p[3] p[4] 모두 첫 번째 요소를 참조하는 표현식
10
Pointer arithmetic and arrays
Pointers And Other Operators 포인터 연산이란 포인터 값을 증가 혹은 감소시키는 연산을 말한다. 포인터 연산이 가능한 연산은 제한되어 있다. 포인터 연산에 따른 실질적인 값의 변화는 포인터 타입에 따라 다르다. 포인터를 나누거나 곱하는 연산은 불가능하다. 예제 프로그램 – 포인터 연산을 이용한 값의 변화를 출력한다.
11
Pointer arithmetic and arrays
Pointers And Other Operators 관계 연산자(Relational operators )는 양쪽의 피 연산자가 모두 포인터인 경우에만 사용이 가능하다. 포인터에서 관계연산자를 사용하는 가장 일반적인 경우는 포인터와 NULL 상수를 비교하는 경우이다.
12
Pointer arithmetic and arrays
포인터를 이용하여 배열의 원소 중 가장 작은 값을 가지는 원소를 찾는 프로그램의 일부이다. 그림은 프로그램이 실행되는 과정을 보인다. pSm은 가장 작은 원소를 가리키기 위해 사용된다. pWalk은 가장 작은 원소를 찾기 위해 배열을 순서대로 탐색한다. pLast는 마지막 원소를 가리킨다.
13
Pointer arithmetic and arrays
Using Pointer Arithmetic 다음은 포인터를 이용한 binary search 함수이다. - list[ ]는 정렬된 data set - endPtr은 현재 list배열의 마지막 원소를 참조 - target은 list에서 찾아야 할 값 - locnPtr은 찾은 원소를 참조할 포인터 변수
14
Pointer arithmetic and arrays
list의 중간 원소를 지정한다 list의 중간 이후 부분일 경우 list의 중간 이전 부분일 경우 target == *midPtr일 경우 찾았는지 여부를 리턴 (찾았다면 target과 *midPtr 이 같으므로 1을 리턴)
15
Pointer arithmetic and arrays
Pointers And Two-Dimensional Arrays 이차원 배열 table의 원소 table[1][3]을 포인터를 사용하여 접근한다면 다음과 같은 표현이 가능하다 *(*(table +i) + j) *(*(table)+1) *(*(table+1)+3)
16
Passing an array to a function
배열을 인자로 하는 함수의 일반적인 호출 형태는 다음과 같다. 배열의 시작 주소값을 인자로 전달한다. 따라서 배열을 인자로 받는 함수의 헤더는 다음과 같을 것이다. 또한 1차원 배열을 인자로 하는 경우 포인터를 이용한 경우도 가능하다.
17
Passing an array to a function
함수의 인자로 배열명을 전달하면, 배열의 시작 주소가 전달된다. 호출되는 함수의 헤더에서는 형식 매개변수(formal parameter)로 포인터 변수를 사용하여야 한다. 표기상의 편리성 때문에 포인터를 매개변수로 선언할 때 배열의 각괄호 표기법을 사용할 수 있다. 이 때 배열로 선언된 형식 매개변수는 실질적으로는 포인터이다. 배열 원소 자체는 복사되지 않는다. 배열명은 배열의 시작 주소값을 가지므로 주소가 전달된다. 사실상 포인터!
18
Passing an array to a function
예제 프로그램 – a[]와 *a가 같음을 보여주는 예제 배열의 주소값과 배열의 길이를 인자로 전달 형식 파리미터가 서로 다르다. 두 함수의 수행 결과는 서로 같다.
19
Passing an array to a function
배열을 인자로 하여 앞의 sum() 함수를 호출했을 때 계산되는 값은 다음 표와 같다. (v는 main 함수에서 선언된 배열이라 가정한다.) 호출 계산 및 리턴되는 값 sum(v, 100) sum(v, 88) sum(&v[7], k - 7) sum(v + 7, 2 * k) v[0] + v[1] v[99] v[0] + v[1] v[87] v[7] + v[8] v[k - 1] v[7] + v[8] v[2 * k + 6]
20
Passing an array to a function
2차원 이상의 배열을 형식 매개변수로 갖는 함수는 (첫 번째를 제외한 나머지 차원의) 배열 크기를 알고 있어야 한다. 예) 다음은 3차원 배열을 형식 매개변수로 갖는 함수의 헤더이다. 예) 다음은 4차원 배열을 형식 매개변수로 갖는 함수의 헤더이다. void func1(int a[][3][4][8]); 예) 다음의 함수 헤더는 컴파일 에러이다. int func2(int a[][][]); 이 곳에 배열 크기를 써줘야 한다.
21
Passing an array to a function
다음은 배열 원소의 값을 2배 하여 저장하는 multiply()함수를 사용한 프로그램이다. multiply()함수의 선언부 배열을 인자로 받는다.
22
Passing an array to a function
pLast 배열의 마지막 요소를 참조한다. 배열 초기화 scanf()를 통해 입력 받는다. multiply() 호출 출력
23
Passing an array to a function
배열과 배열크기를 인수로 받는다. 배열 원소 값 * 2
24
Passing an array to a function
다음은 multiply() 함수를 사용한 프로그램의 구조이다. 포인터변수 pWalk가 포인터연산을 통해 입력, 출력, 계산될 원소를 바꿔가며 참조한다. 실행 결과
25
Memory allocation functions
Static memory allocation 정적 메모리 할당은 소스프로그램 안에서 메모리의 선언과 정의가 완벽하게 명시되어 있어야 한다. 실행 시간 동안에 할당된 byte 수 등이 변할 수 없다. 입력되는 데이터 길이에 대해 정확하게 알고 있어야만 사용 가능하다.
26
Memory allocation functions
동적 메모리 할당 메모리의 난비를 최소화하기 위해 프로그램의 실행 중에 입력되는 데이터에 맞게 기억공간이 할당되어야 한다. 메모리의 동적 할당 메모리의 동적 할당과 해제 기능은 라이브러리로 구현되어 있고, 이를 이용하기 위해서는 반드시 포인터를 이용한다. 동적할당이란 프로그램 실행 중에 ,즉 run time때 메모리 영역을 할당한다는 뜻이다.
27
Memory allocation functions
Memory management functions 메모리의 동적 할당에 사용되는 메모리 할당 함수들 malloc(), calloc(), realloc()은 메모리를 할당하기 위한 함수 free()는 더 이상 사용하지 않는 메모리를 리턴하는 함수 함수를 사용하기 위해서는 “stdlib.h” 헤더파일을 포함해야 한다. #include<stdlib.h>
28
malloc() malloc() 함수는 메모리를 할당하기 위한 함수이다. 함수의 프로토타입은 다음과 같다.
malloc() 함수는 할당한 메모리의 시작주소를 void 포인터로써 리턴한다. 할당에 실패한 경우 NULL을 되돌려 준다. malloc() 은 크기가 size인 객체(기억 장소)를 할당한다. The type ,size_t, is defined in several header files including <stdio.h>. The type is usually an unsigned integer.
29
malloc() 다음은 malloc() 함수의 일반적인 사용 예이다.
pInt는 한 개의 int형 원소에 대한 데이터를 저장할 수 있는 크기의 메모리가 할당 n개의 int 형 원소를 저장할 수 있는 메모리를 할당 받기 위해서는 malloc(sizeof (int) * n) 만일 malloc() 함수가 메모리 영역을 할당하는데 실패한다면 NULL 포인터를 리턴할 것이다. int 타입 포인터 <malloc함수 호출 예>
30
malloc() 예제프로그램 - malloc을 이용한 변수 할당 p *p malloc 함수로 할당된 영역
int형 1개 크기의 메모리 할당하고 그 주소값을 p에 넘겨준다. 새로 할당된 메모리영역에 접근 p *p malloc 함수로 할당된 영역 p가 새로 할당된 영역을 가리킨다.
31
malloc() 예제프로그램 – 메모리를 동적으로 할당 받아 배열로 사용하는 프로그램 20바이트의 기억공간 할당
할당 받은 메모리를 배열처럼 사용하여 값을 입력 받는 부분
32
Contiguous Memory Allocation - calloc()
할당 받은 메모리를 사용할 하나의 원소 크기와 전체 원소의 개수를 개별적인 인자로 받는다 . calloc() 함수는 메모리를 할당하면서 해당 메모리를 0으로 초기화 시킨다. <calloc함수 호출 예> malloc()과 calloc()의 차이점
33
Reallocation of Memory - realloc ()
함수의 프로토타입은 다음과 같다. 즉, ptr이 현재 할당하고 있는 메모리의 크기를 newSize로 변경한다. ptr이 가리키는 곳의 size를 int의 크기 * 15 로 변경한다.
34
calloc() & realloc() 예제 프로그램 - realloc함수를 이용한 양수값 입력 프로그램
할당 받은 기억공간이 남아있으면 데이터를 저장한다. 기억공간이 부족하면 크기를 늘려서 재할당 받는다.
35
Releasing Memory - free ()
동적으로 할당 받은 메모리 영역에 대하여 반환하는 함수 free() 함수의 프로토타입은 다음과 같다. 사용하지 않는 메모리에 대한 계속적인 할당은 메모리 사용의 낭비의 단점이 있기 때문에 동적으로 할당 받은 필요 없는 메모리 영역에 대해서는 free()를 통해서 메모리를 반환하도록 한다. free() 는 ptr이 가리키는 기억 장소를 해제한다. 단, ptr이 NULL일 때는 아무 일도 하지 않는다. ptr은 malloc(), calloc(), realloc()에 의하여 이전에 할당되었던 기억 장소의 포인터이어야 한다.
36
Releasing Memory - free ()
Caution! 동적으로 할당한 기억 장소 영역은 책임지고 해제하지 않으면 안 된다. 영역을 해제할 때까지는 반드시 포인터를 기억해 두어야 한다.
37
Releasing Memory - free ()
예제프로그램 - 정수를 1개 할당, 해제하는 프로그램 메모리 4byte를 할당받음 제대로 할당되었는지 확인 메모리 4byte를 해제
38
Dynamic allocation of array
malloc은 8개의 int를 위한 기억 장소를 할당해 그 시작 주소값을 되돌려 준다. 포인터 변수가 있으면 포인터가 가리키는 영역을 배열처럼 사용가능 포인터 변수 p가 가리키는 원소의 i번째 원소를 나타내는 표현식 *(p+i) , p[i] int *p; p = (int *)malloc(8 * sizeof(int)); p *p malloc 함수로 할당된 영역
39
Array of pointers 여러 개의 문자열을 처리할 때, 포인터변수가 문자열의 개수만큼 필요
포인터변수들을 하나씩 선언하지 않고 포인터배열을 이용가능 포인터배열은 다양한 크기의 데이터 배열을 원소로 가질 수 있다. 포인터와 메모리 관리 함수를 사용함으로써 포인터배열 사용한다. 위의 데이터를 저장하기 위해 2차원배열(5*7)을 이용한다면 메모리의 많은 낭비를 초래한다.
40
Array of pointers 2차원 배열을 포인터배열로 나타내면 다음과 같다.
41
Array of pointers 예제프로그램 다수의 문자열을 입력 받아 이를 포인터 배열을 이용하여 저장하고 출력
문자열 출력 함수 선언 입력할 문자열의 개수 입력 포인터 배열의 동적 할당 문자열을 저장할 메모리 할당
42
Array of pointers 입력이 끝난 후에 포인터배열을 널 포인터로 마감한다.
문자열 출력을 위해 str_prn를 호출한다. 문자열을 저장한 메모리 반환 입력된 물자열 출력
43
포인터 응용의 자주 실수하는 에러, 응용 팁 일반적인 에러 int *a[5]; //포인터배열 int (*a)[5];
5개의 포인터를 원소로 갖는 배열 …… [ ][5] 배열
44
포인터 응용의 자주 실수하는 에러, 응용 팁 int ary[]; 에 대하여 int table[]; 에 대하여
Similar presentations