본문 바로가기

오래된 흔적/C로 배우는 알고리즘 1

2.4 포인터(Pointer)

<일반 포인터의 2가지 구성 요소>

1. 주소를 내용으로 가진다.
2. 주소가 가리키는 곳에 저장되어 있는 데이터 형(data type)을 알 수 있다.

<void 포인터의 구성 요소>

1. 주소를 내용으로 가진다. 
2. 주소가 가리키는 곳에 저장되어 있는 데이터 형(data type)을 알 수 없다. 
(그러므로, 형변환 연산자(casting operator)로 강제 형변환 후 일반 포인터 처럼 사용해야함)

void *vptr;        // void 타입의 포인터 vptr 선언
int i;
i = *vptr;          // 에러. vptr은 형을 알 수 없는 void 타입이다.
i = *(int*)vptr;  // vptr을 (int*)으로 형변환 한 후 vptr이 가리키고 있는 주소의 내용(*)을 i에 저장함


<포인터 연산잔>

1. & (address of) : 변수의 주소를 구함
2. * (dereference) : 가리키는 주소의 내용을 참조함
3. +, - : 주소를 옮겨줌
4. -> : 구조체와 함께 작동하여 구초제의 포인터의 멤버들을 접근하게 해줌.

int *iptr;     // int형의 포인터 iptr을 선언
int i, j;       // int형의 i, j 선언
iptr = &i;    // iptr에 i의 주소를 대입
j = *iptr;    // j에 iptr이 가리키고 있는 주소의 값을 대입
/* 즉, j = i 의 결과 */


<포인터의 포인터>

1. 포인터의 포인터를 사용하는 90% 이상이 문자열의 배열을 다룰 때임.

char str1[] = "This is string.";           // 배열의 형식
char *str2 = "This also is string.";     // 포인터의 형식
1. "" 사이의 문자열은 정적 데이터 영역에 저장됨.
2. = 연산자와 쓰일때는 그 선두 번지를 의미함.
3. str1은 배열의 이름이기 때문에 자체의 주소를 저장하기 위한 공간을 갖지 않는 상수.
4. str2는 포인터이기 때문에 주소를 저장하기 위한 공간을 할당받음. 
5. 그러므로 str2의 내용인 주소값은 얼마든지 변경이 가능함.


<함수 포인터>

1. 선언 방식 : 리턴 타입과 인자 리스트의 데이터 타입만을 나열한 뒤에 포인터의 이름앞에 *를 붙이고 괄호를 씌움.
2. 함수 포인터는 데이터를 가리키는 포인터가 아닌 코드를 가리키는 주소
3. 배열의 시작주소가 배열명 그 자체이듯이 어떤 함수의 시작 주소는 함수명 그 자체이다. 

int sigma(int n)
{
   ...
}
* sigma함수를 가리키는 포인터 선언
int (*fptr) (int);
fptr = sigma;


<"Call by Value" or "Call by Reference">

1. 함수를 호출하는 쪽에서 값을 바꿀건지 아닌지의 판단에 따라 선택적으로 사용하면 됨. 
2. 무엇이든 간에 함수 파라미터로 넘겨지는 순간 복사가 일어남.