[C] 포인터 활용

1 minute read

포인터 개념은 단순하지만 사용사례가 헷갈리기 쉬우므로 몇가지 간단한 함수를 통해 알아보고자 한다. 첫번째는 증감연산자와 포인터를 함께 쓸 때이다. *a++, *++a 두 개는 operation에서 설명한 것과 같이 연산자의 우선순위에 따라 처리된다. 먼저 *a++의 경우 a와 가까운 단항연산자인 역참조 연산부터 수행되어, 주소를 타고 값을 받아와 출력하고 이후 포인터 변수 a의 주소를 1만큼 증가시킨다. *++a의 경우 a의 주소를 1만큼 먼저 증가시키고 변경된 주소를 타고 해당하는 값을 반환한다. (*a)++ 의 경우에는 역참조 연산을 우선적으로 수행하여 값을 반한한 뒤 값을 1만큼 증가시킨다. 이해를 돕기 위해 만든 간단한 예제를 살펴본다.

    #include <stdio.h>

    int main(){
        char a[6]="ABCDE";
        char *p = a;

        printf("%c\n", *++p);
        printf("%c\n", *p++);
        printf("%c\n", *p);
        printf("%c\n", (*p)++);
        printf("%c\n", *p);

        return 0; 
    }
B
B
C
C
D

두 값을 바꾸는 swap 함수의 경우 값을 일반적으로 받아와 바로 치환하지만, 포인터 변수 형태로 주소를 받아와 치환할 수도 있다.

    #include <stdio.h>

    void swap(int *a, int *b){
        int temp = *a;
        *a = *b;
        *b = temp;
    }


    int main(){
        int a=4;
        int b=27; 
        printf("%d %d\n", a,b);

        swap(&a,&b);

        printf("%d %d\n", a,b);

        return 0; 
    }
4 27
27 4

문자열 배열에 대해 문자열 복사와 길이를 구하는 간단한 함수를 만들 수 있다. 문자열 복사의 경우 while문을 활용하여 대상 문자열과 담을 배열의 주소를 통해 참조하면 주소를 통해 접근하여 값을 대입할 수 있다. 문자열의 끝까지 주소가 이동하면 마지막 값인 NULL 값이 반환되므로 while문이 자동으로 종료된다. 문자열 길이 계산의 경우 포인터 변수식을 사용하여 들어있는 문자열 길이를 정확하게 계산할 수 있다. sizeof 함수를 사용하여 문자열의 길이를 구하게 되면, NULL 값이 포함된 길이가 구해질 뿐만 아니라 만약 배열의 크기가 문자열의 크기보다 큰 경우 배열 크기 값을 출력하기 때문에 정확한 문자열 길이를 구할 수 없다 (물론 string.h 파일 내의 strlen 함수를 사용해도 정확한 길이를 계산할 수 있다).

    #include <stdio.h>

    void copy_string(char *a, const char *b){
        while(*a++ = *b++);
    }

    int len_string(const char *a){
        int count=0;
        while(*a++) count++;
        return count; 
    }

    int main(){
        char a[6];
        char b[6]="Apple";

        copy_string(a,b);

        printf("%s\n",a);
        printf("%s\n",b);

        printf("%d", len_string(a));

        return 0; 
    }
Apple
Apple
5

추가적으로 sizeof 함수를 직접적으로 포인터 변수에 사용하게되는 경우 항상 4B 값을 반환한다. 이는 포인터 변수의 크기가 메모리 주소를 나타내기 위한 크기인 4B를 나타내기 때문이며, 데이터 타입과 상관없이 포인터 변수 자체의 크기를 반환함을 이해해야한다. (시스템 운영체제에 따라 8B로 나타나기도 한다)

    #include <stdio.h>

    int main(){
        int a[10];
        int *pa = a;
        char *pb; 
        float *pc;

        printf("%d\n", sizeof(a)/sizeof(a[0]));
        printf("%d\n", sizeof(a));
        printf("%d\n", sizeof(pa));
        printf("%d\n", sizeof(pb));
        printf("%d\n", sizeof(pc));

        return 0; 
    }
10
40
8
8
8