코딩/C언어

C언어 포인터

zz! 2025. 4. 25. 17:35
728x90

 

포인터란?

메모리 주소를 저장하는 변수이다. 어떤 변수의 값을 직접 저장하지 않고, 그 변수가 저장된 위치(주소)를

가리킨다.

예제 소스코드

#include <stdio.h>

int main() {
    int a = 10;
    int *p; // 포인터 선언

    p = &a; // 변수 a의 주소를 p에 저장

    printf("a의 값: %d\n", a);
    printf("a의 주소: %p\n", &a);
    printf("p에 저장된 값(주소): %p\n", p);
    printf("p가 가리키는 값: %d\n", *p); // 역참조

    return 0;
}

결과

*p는 p가 가리키는 주소의 값에 접근하는 걸 의미한다. (역참조)

 

2. 포인터를 이용한 값 변경

출력

함수에 값을 넘길 때 포인터를 사용하면 원본 값을 수정을 할 수 있다.

 

3. 포인터와 배열

#include <stdio.h>

int main() {
    int arr[3] = {1, 2, 3};
    int *p = arr;

    for (int i = 0; i < 3; i++) {
        printf("arr[%d] = %d, *(p + %d) = %d\n", i, arr[i], i, *(p + i));
    }

    return 0;
}

결과

배열 이름 자체가 배열의 첫 번째 요소의 주소를 의미하므로 p = arr 은 p = &arr[0]과 같다

포인터 연산 *(p + i)는 arr[i]와 같다.

비유로 이해하기

a 는 진짜 값(돈)

p는 지갑에 든 돈(값을 가리키는 주소)

pp는 지갑이 있는 위치를 알고 있는 사람(주소의 주소)

--> **pp는 결국 지갑을 꺼내서 돈을 꺼내는 느낌이다.

4. 이중 포인터

#include <stdio.h>

int main() {
    int a = 100;
    int *p = &a;
    int **pp = &p;

    printf("a = %d\n", a);
    printf("*p = %d\n", *p);
    printf("**pp = %d\n", **pp);

    return 0;
}

결과

**pp 는 a에 도달하는 것이다.

포인터를 가리키는 포인터 -> 포인터 배열이나 다차원 배열 다룰 때 유용하다

a = 정수 변수고 값은 100

int *p p는 a의 주소를 저장하는 포인터

*p는 p가 가리키는 주소에 있는 값 -> *p == 100

 

5. 포인터를 리턴하는 함수

#include <stdio.h>

int* getPointer() {
    static int x = 42;
    return &x;
}

int main() {
    int *ptr = getPointer();
    printf("값: %d\n", *ptr);
    return 0;
}

static 을 사용하면 지역변수이지만 함수 종료 후에도 살아있다.

일반 지역 변수는 함수가 끝나면 사라지므로 포인터로 리턴하면 안된다.

 

728x90