Notice
Recent Posts
Recent Comments
Link
«   2026/02   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
Archives
Today
Total
관리 메뉴

사고쳤어요

C 포인터 본문

C

C 포인터

kevinmj12 2025. 4. 2. 18:29

변수는 위와 같이 0x1000이라는 메모리 주소에 저장된 값을 불러오기 위한 메모리 주소의 식별자이다.

변수 덕분에 메모리 주소를 외울 필요 없이 편리하게 메모리로부터 값을 불러올 수 있다.

포인터는 포인터 변수의 줄임말로 메모리의 주소값을 저장하고 있는 변수이다.

이를 한 번 더 풀어서 설명하면, 메모리의 주소값을 저장하고 있는 메모리의 주소값을 저장하는 식별자이다.

메모리 주소 0x01에 저장된 값 65를 사용하기 위한 변수 a가 있을 때,

메모리 주소 0x21에 저장된 값 0x01을 사용하기 위한 변수 pA가 포인터이다.

 

포인터 사용 방법

C에서는 포인터 변수를 사용할 때 일반 변수와 구분하기 위해 변수명 앞에 * 기호를 붙인다.

예를 들면 int *pA; char *pB; 와 같이 선언하면 된다.

 

선언을 했다면, 변수에 주소값을 할당해주어야 할 것이다.

C에서는 변수의 주소값을 나타내기 위해 변수명 앞에 & 기호를 붙인다.

예를 들어 int *pA = &a; 와 같이 선언하면, 포인터 변수 pA는 변수 a의 주소값을 저장한다는 의미이다.

 

포인터가 선언이 되었다면 포인터에는 메모리 주소가 저장되어 있을 것이다.

그런데 이를 활용하여, 포인터가 저장하고 있는 메모리 주소가 저장하고 있는 값을 불러올 수 있다.

예를 들어 int *pA = &a; 가 있을 때 printf("%d", pA);를 실행하면 a의 메모리 주소가 출력된다.

그리고 pA의 앞에 * 기호를 붙여 printf("%d", *pA);를 실행하면 a의 값이 출력된다.

여기서 *pA는 처음 pA를 선언할 때 int *pA = &a;의 *pA와 다른 의미라는 것을 알아야 한다.

 

int main(){
    int a = 100;
    int *pA = &a; // 여기서 *pA는 포인터 변수라는 뜻의 *

    printf("a: %d \n", a);      // a: 100
    printf("&a: %x \n", &a);    // &a: 61ff18 
    printf("*pA: %d \n", *pA);  // *pA: 100, 여기서 *pA는 가리키는 메모리 주소의 실제 값이라는 뜻의 *
    printf("pA: %x \n", pA);    // pA: 61ff18
}

 

배열과 포인터

C에서는 배열을 사용하기 위해 int arr[5] = {1, 2, 3, 4, 5}와 같이 사용할 수 있다.

배열의 각 요소에 접근하기 위해서는 인덱스를 사용하여 arr[0], arr[1], ... 과 같이 접근이 가능하다.

그리고 배열의 이름 arr은 배열의 첫 번째 요소의 주소값을 가리키는 포인터 변수의 역할을 한다.

즉 arr은 arr[0]의 주소값, &arr[0]과 같다.

int main(){
    int arr[5] = {1, 2, 3, 4, 5};
    
    printf("&arr[0]: %x \n", &arr[0]);  // &arr[0]: 61ff0c
    printf("arr: %x \n", arr);          // arr: 61ff0c 
}

 

그렇다면 배열의 이름도 포인터이니 다른 포인터 변수 값으로 값을 바꿀 수 있을까?

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

    arr = pA; // 오류 발생
}

배열의 이름을 다른 값으로 변경하려 하면 오류가 발생하는데, 상수이기 때문이다.

배열의 이름은 포인터 상수로 가리키고 있는 주소값을 변경할 수 없다.

 

함수와 포인터

void func(int *pArr){
    for (int i = 0; i < 5; i++){
        printf("%d \n", *(pArr + i));
    }
}

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

    func(arr);
}

// output
// 1 
// 2 
// 3
// 4
// 5

함수의 파라미터로 포인터 변수를 받을 수 있다.

위의 예시에서는 *pArr이라는 이름의 포인터를 통해 그 메모리 주소에 저장된 값을 출력한다.

그리고 func(arr)이 호출되면 pArr에 arr의 값, &arr[0]이 복사되어 저장된다.

 

int plus(int a, int b){
    return a + b;
}

int main(){
    int (*fPtr)(int pa, int pb); // 함수 포인터
    fPtr = plus;

    printf("%d", fPtr(3, 5)); // 8
}

포인터가 가리키는 주소값을 함수로 지정할 수도 있다.

위 코드에서 fPtr은 함수 plus를 가리키게 되어 있고, 그 주소값을 통해서 plus함수를 호출하고 있다.

 

'C' 카테고리의 다른 글

연산자  (0) 2025.04.02
C 변수와 상수  (0) 2025.03.28