기초 - 포인터

임재현·2021년 4월 26일
0

C

목록 보기
6/10

포인터의 개념

  • 지금까지의 변수는 그 자체로 자신의 자료형에 맞는 값을 저장했다.
  • 포인터(Pointer)변수는 특이한 변수로, 메모리 주소를 저장한다.
  • 포인터는 특정한 변수 자체가 존재하는 메모리 주소의 값을 가진다. (포인터도 변수기 때문에 당연히 특정한 주소값을 가진다.)
  • 다음 예제에서는 기존에 a를 이용해서도 5라는 값을 찾을 수 있지만 포인터 변수인 b를 이용해서도 5라는 값을 찾을 수 있다.

A와 B 둘다 변수라고 할 수 있다. 각기 다른 주소에 기록된 변수인데, B는 포인터 변수이기 때문에 A라는 변수의 주소를 값으로 가지고 있는 것.

  • int *b = &a;처럼 "선언할 때" 쓰는 *는 포인터 변수임을 알려주기 위한 목적을 가진다.(이 때 *는 포인터)
  • 이후에 *b라고 쓰게 되면, 이것은 포인터 변수 b가 가리키는 주소의 값을 의미한다. 다시말해 5라는 값 자체가 된다.(이때 *는 간접참조연산자 라고 한다.)

    예시
#include <stdio.h>

int main(void){
    int a = 5;
    int *b = &a;
    printf("%d\n",*b);
    return 0;
}

포인터 변수 b가 가리키고 있는 a의 값을 출력하므로 출력값은 5가 된다.

int main(void){
   int a = 5;
   int *b = &a;
   printf("%d", b);
}

출력값 : -486066420
간접참조연산자를 안붙이고 b를 출력하면 a의 주소가 출력되었다.

배열의 각 원소의 주소 값 출력하기

#include <stdio.h>

int main(void){
    int a[] = {1,2,3,4,5,6,7,8,9,10};
    int i;
    for(i = 0; i < 10; i++){
        printf("%d\n", &a[i]);
    }
}

결과 :

-354949408
-354949404
-354949400
-354949396
-354949392
-354949388
-354949384
-354949380
-354949376
-354949372

int형이 4byte므로 4씩 증가하는 모습을 볼 수 있다.(아래에서 위로). 배열이란 걸 이용하게 되면 동일한 하나의 자료형을 연속적인 공간에 배치할 수 있다. 다시말해, 4바이트씩 총 10개를 차지하니깐 총 40바이트만큼 차지하는 배열임을 주소연산자를 사용해서 확실하게 확인할 수 있다.

포인터의 강력한 기능

  • 포인터는 컴퓨터 시스템의 특정한 메모리에 바로 접근할 수 있다.
  • 따라서 기존에 존재하던 중요한 메모리 영역에 접근하지 않도록 해야한다.

다음과 같은 코드는 굉장히 위험한 코드이다.

int *a = 0x3384735;
*a = 0;

포인터는 다중으로도 사용할 수 있다.

#include <stdio.h>

int main(void){
    int a = 5;
    int *b = &a;
    //여기까지는 포인터 b가 a의 주소값을 가리키고 있다.
    //포인터 b또한 컴퓨터에 기록된 일종의 변수이다.
    int **c = &b;
    //그래서 포인터의 포인터임을 알려주는 **을 사용해 포인터 변수인 b의 메모리 주소값을 가리키도록 할 수 있다.
    printf("%d\n", **c);
    //포인터 변수 c가 가리키고 있는 주소가 b인 거니까, 그 b가 가리키고 있는 값을 또 참조해야 하므로 **을 붙여줬다.

    //출력값 : 5
}

배열과 포인터

  • 배열과 포인터는 사실 동일하다.
  • 배열을 선언한 이후에는 그 이름 자체가 포인터 변수와 동일하다.
int main(void){
    int a[] = {1,2,3,4,5,6,7,8,9,10};
    int *b = a;     //주소연산자를 안붙였다. a라는 배열의 이름자체를 주소값으로 사용하고 있다.
    //사실 내부적으로 배열이름 자체는 주소값을 가지고 있기 때문에 이렇게 사용할 수 있다.
    printf("%d",b[2]);
    //출력값 : 3
    return 0;
}

포인터는 특정한 변수가 메모리 상에 존재하는 위치 주소를 저장한다.

포인터는 특정한 메모리 주소에 바로 접근할 수 있으므로 조심스럽게 사용해야 한다.

profile
임재현입니다.

0개의 댓글