본문 바로가기

C Langauage

Chapter 12. 포인터 고급

Chapter 12. 포인터 고급
1. 포인터의 활용
 - 포인터 배열

 데이터형 * 배열명[크기];
     int    *   parr[3]   ;

 int a=10, b=20, c=30;
 int * parr[3] = {&a, &b, &c};

  ‧ 포인터와 배열을 같이 사용해 주소들을 저장하는 배열을 말하며 같은 타입의 포인터가 여러 개 필요한 경우 사용된다.
  ‧ 구조체를 데이터형으로도 사용 가능하다.
 - 배열에 대한 포인터

 데이터형 (*배열명) [크기];
     int     (*parr)   [5]  ;

 int arr[5] = {1,2,3,4,5};
 int (*parr) [5] = &arr;

  ‧ 배열 전체를 가리키는 포인터이다.
  ‧ 배열 전체를 가리키기 위해서 대상이 되는 배열과 포인터 배열의 데이터형과 크기가 같아야한다.
  ‧ 포인터 배열과는 다르다.
  ‧ 배열 전체의 주소를 구하려면 배열 이름 앞에 Ampersand(&) 연산자를 써줘야 한다.
  ‧ 배열의 이름인 arr는 배열의 시작 주소이고, 배열의 첫 원소의 주소와 같다.
  ‧ 배열의 원소에 접근 시 포인터 연산을 이용한다.
  ◦ 포인터 연산을 이용한 arr의 첫 번째 원소의 표현

 *(arr+i)
 *((*parr)+i)
 (*parr)[i]
 parr[0][i]

     ※ 항상 []가 *보다 우선순위가 높다.
  ‧ 주로 이차원배열의 한 묶음을 가리키는 용도로 사용
  ◦ 이차원배열의 한 묶음씩을 가리키는 포인터 배열

 - 함수에 대한 포인터

 리턴형 (*포인터명) (매개변수);
    int    (*pfunc)     (int);

 int func(int);
 int (*pfunc) (int);
 pfunc = &func;

  ‧ 함수의 주소를 저장하는 포인터 변수
  ‧ 함수의 이름은 함수의 시작주소를 의미해 해당 포인터 뒤에 함수의 이름을 Ampersand(&)와 같이 써주면 포인터가 함수의 시작주소를 가리키는

     포인터가된다.
  ‧ 함수의 주소를 가리키기 위해서는 리턴형과 매개변수의 데이터형이 같아야한다.
 - 함수에 대한 포인터형

 typedef 리턴형 (*포인터형명)(매개변수);
 typedef   int   (*FUNCPTR)   (int)   ;

 

  ‧ 함수에 대한 포인터를 사용할 때마다 포인터의 긴 이름을 호출해야 되기 때문에 함수에 대한 포인터형을 새로 정의해 사용하는 기능이다.
  ‧ typedef와 함께 사용되는 점을 제외하면 함수에 대한 포인터와 비슷하지만 함수에 대한 포인터형은 데이터형이고 함수에 대한 포인터는 변수이다.

 

2. 포인터를 이용한 메모리 관리와 동적 할당
 - 메모리
  ‧ 프로그램이 실행되는 동안 데이터가 저장되는 공간
  ‧ 운영체제에 의해 할당되는 메모리 공간

  ◦ 코드(Code) 영역 : 실행할 프로그램의 코드가 저장되는 공간으로 CPU는 코드영역에 저장된 명령문을 하나씩 꺼내 실행한다.
  ◦ 데이터(Data) 영역 : 전역변수와 static변수가 할당되는 영역으로 프로그램 시작과 동시에 할당되어 종료 시까지 남아있는 특징의 변수가 저장되는 공간이다.
  ◦ 힙(Heap) 영역 : 프로그래머가 원하는 시점에 메모리 공간에 할당 및 소멸을 하기 위한 공간이다.
  ◦ 스택(stack) 영역 : 지역변수와 매개변수가 할당 되는 공간으로 함수를 빠져나가면 소멸되는 변수를 저장하는 공간이다.
  ‧ 메모리의 종류
  ◦ 정적 메모리
   ▹ 메모리가 언제 할당되고 해제 될지, 얼마나 할당될지 컴파일 시간에 결정되는 메모리
   ▹ 스택(stack) 영역과 데이터(Data) 영역에 할당되는 메모리
  ◦ 동적 메모리
   ▹ 메모리가 언제 할당되고 해제 될지, 얼마나 할당될지 실행 시간에 결정되는 메모리
   ▹ 힙(Heap) 영역에 할당되는 메모리
   ▹ melloc함수와 free함수를 이용한다.
 - 동적 메모리 할당 및 해제 함수
  ‧ melloc

 void *melloc(size_t size);

 int * ptr1=(int*)malloc(sizeof(int));

 int * ptr2=(int*)malloc(sizeof(int)*7);

  ◦ 인자로부터 넘겨받은 size 바이트 크기만큼 동적 메모리를 할당하고 할당된 메모리의 주소를 리턴하고 동적 메모리를 할당할 수 없을시 NULL 리턴한다.
  ◦ sizeof로 정해진 크기에 숫자를 곱해 배열을 만들 수도 있으며 변수명+1을 해주면 두 번째 변수(두 번째 인덱스)로 접근이 가능하다.
  ◦ 리턴 되는 주소는 void 포인터 타입이기 때문에 반드시 형 변환을 이용해서 사용한다.
     ※ melloc함수의 리턴형이 void인 이유는 인자로 숫자만 하나 전달받기 때문에 할당하는 메모리의 용도를 알지 못한다.

        따라서 메모리의 포인터 형을 결정짓지 못하기 때문에 형변환의 과정을 거쳐서 할당된 메모리의 주소 값을 저장한다.
  ‧ free

 void free(void* memblock);

  ◦ 동적 메모리에 인자로 넘겨준 포인터가 가리키는 주소를 해제한다.

  ◦ 동적 메모리는 일반 변수와 다르게 사용이 끝나면 반드시 해제해야 한다.
  ◦ 동적 메모리를 해제한 다음에는 동적 메모리를 가리키던 포인터변수에 NULL을 대입하는 것이 안전하다.


'C Langauage' 카테고리의 다른 글

Chapter 13. 파일 입출력  (0) 2015.08.05
Chapter 11. 구조체(Struct)  (0) 2015.08.05
Chapter 10. 전처리기(Preprocessor)  (0) 2015.08.05
Chapter 9. 문자열(String)  (0) 2015.08.05
Chapter 8. 포인터(Pointer)  (0) 2015.08.05