본문으로 건너뛰기

포인터와 예제

1. 포인터의 개요

1.1. 포인터 변수의 개념

  • 정의:
    포인터 변수는 변수의 주소를 값으로 저장하는 변수입니다

  • 주소:
    모든 변수는 메모리 상에 고유한 주소를 가지며, 포인터 변수는 이러한 주소를 저장하여 다른 변수에 간접적으로 접근할 수 있게 합니다.


1.2. 포인터 변수의 선언 및 초기화

  • 선언:
    데이터타입 *포인터변수이름; 형식으로 선언합니다.
    예시:

    int *b; // 정수형 변수의 주소를 저장할 포인터 변수 b 선언
  • 초기화:
    포인터변수이름 = &변수이름; 형식으로 변수의 주소를 포인터 변수에 할당합니다.
    여기서 &는 주소 연산자입니다.

    예시:

    int a = 10;
    int *b;
    b = &a; // b에 a의 주소 저장

1.3. 포인터 변수의 데이터 타입 일치

  • 포인터 변수도 데이터 타입을 가집니다.
  • 포인터변수가 가리키는 변수의 데이터타입과 포인터변수의 데이터타입이 일치해야 함

올바른 예:

int i = 10;
int *ip;
ip = &i;

오류 예:

float i = 10;
int *ip;
ip = &i; // 타입 불일치로 인한 오류

1.4. 포인터 연산자

  • 주소 연산자 (&):
    변수의 주소는 & 연산자로 접근 가능함 예: 변수 a의 주소는 &a로 얻을 수 있습니다.

  • 간접 참조 연산자 (*):
    포인터변수에 들어있는 주소의 값을 가져오는 연산자 예: 포인터 변수 b가 저장하고 있는 주소에 있는 값은 *b로 접근할 수 있습니다.

  • 주소 출력:
    주소를 출력하기 위해서는 printf 함수에서 %p 또는 %u 변환 문자를 사용합니다6, p.24).


2. 포인터 활용 예제

2.1. 포인터 변수와 배열

  • 배열의 이름:
    배열의 이름은 배열의 시작 주소를 저장하는 포인터처럼 동작합니다.

    "배열의 이름은 배열을 시작하는 주소를 저장함"

  • 포인터를 이용한 배열 접근:

    int arr[5] = {1, 2, 3, 4, 5};
    int *arptr;
    arptr = arr; // 배열의 시작 주소를 포인터에 할당
    • arptr[i]를 사용하여 배열처럼 접근하거나, *(arptr + i)를 사용하여 간접 참조 연산과 포인터 연산을 통해 배열 요소를 접근할 수 있습니다
    • 마찬가지로 *(arr + i)와 같이 배열의 이름에 직접 간접 참조 연산과 포인터 연산을 적용하여 요소를 접근할 수도 있습니다

2.2. 포인터 변수의 연산

포인터 변수는 값의 증가/감소 뿐만 아니라 주소의 증가/감소 연산도 가능합니다

  • ptr++ (주소 증가):
    포인터 변수 자체가 다음 메모리 위치로 이동합니다.

    "포인터변수는 4byte 단위로 이동합니다." 이는 포인터가 가리키는 자료형의 크기만큼 주소가 증가함을 의미합니다.
    (예: int는 4바이트, double은 8바이트, char는 1바이트)

    printf("ptr=%p *ptr=%d\n", ptr, *ptr); // ptr의 값이 증가, *ptr은 새로운 주소의 값
  • (*ptr)++ (가리키는 값 증가):
    포인터가 가리키는 메모리 위치에 저장된 값을 1 증가시킵니다.
    포인터 변수 자체의 주소는 변하지 않습니다.

    printf("ptr=%p *ptr=%d\n", ptr, *ptr); // ptr은 변함없고, *ptr의 값이 1 증가
  • *(++ptr) (주소 증가 후 참조):
    포인터 변수를 먼저 증가시킨 후, 증가된 주소에 있는 값을 참조합니다.

    printf("ptr=%p *ptr=%d\n", ptr, *ptr); // ptr의 값이 증가, *ptr은 새로운 주소의 값
  • *(--ptr) (주소 감소 후 참조):
    포인터 변수를 먼저 감소시킨 후, 감소된 주소에 있는 값을 참조합니다.

    printf("ptr=%p *ptr=%d\n", ptr, *ptr); // ptr의 값이 감소, *ptr은 새로운 주소의 값

3. 학습 정리 (핵심 요약)

  • 포인터 변수 개념:
    변수의 주소를 값으로 저장하는 변수

  • 선언 및 초기화:

    int *b;
    b = &a;
  • 데이터 타입 일치:
    포인터가 가리키는 변수와 포인터 변수의 데이터 타입은 일치해야 합니다

  • 핵심 연산자:

    • & (주소 연산자): 변수의 주소 접근 (예: &a는 a의 주소)
    • * (간접 참조 연산자): 포인터가 저장한 주소의 값 접근 (예: *b는 b가 가리키는 값)
  • 배열과 포인터:
    배열의 이름은 시작 주소를 저장하며, 포인터 변수처럼 배열에 접근하고 조작할 수 있습니다

  • 포인터 연산:
    주소 증가/감소 (++, --) 연산이 가능하며, 이는 자료형의 크기에 따라 주소값이 변경됩니다