열렬히.뛰기

포인터 활용

Language > 프로그래밍 언어 > C > 포인터 활용

이중 포인터

c
#include <stdio.h>

int main() {
	int i = 100;
  int *p = &i;  // 포인터 p
  int **q = &p; // 이중 포인터 q

  *p = 200;
  printf("i = %d\n", i);

	**q = 300;
	printf("i = %d\n", i);
}
  • 포인터 q → 포인터 p → 변수 i
  • 즉, 포인터를 가르키는 포인터로 생각하면 된다.
  • 다른 포인터와 마찬가지로 4바이트가 필요
  • 외부에서 정의된 포인트 값을 함수의 인수로 받아 변경하려고 할 때 많이 쓴다.

포인터 배열

배열의 원소가 포인터.

c
#include <stdio.h>
int main() {
     int i, n;
     char *fruits[ ] = {
          "apple", "blueberry", "orange", "melon"
     };

     n = sizeof(fruits)/sizeof(fruits[0]);
     for(i = 0; i < n; i++) {
         printf("%s \n", fruits[i]);
     }
}

배열 포인터

배열을 가리키는 포인터

c
#include <stdio.h>

int main() {
    int a[5] = { 1, 2, 3, 4, 5 };
    int (*pa)[5];
    int i;

    pa = &a;
    for(i=0; i<5; i++) {
        printf("%d \n", (*pa)[i]);
    }

}

함수 포인터

함수를 가르키는 포인터.

포인터에 저장된 함수 주소를 이용해 함수를 호출한다.

c
#include <stdio.h>
int add(int x, int y) {return x+y;}
int sub(int x, int y) {return x-y;}

int main() {
    int result;

    int (*pf)(int, int); // 함수포인터 정의
    pf = add; // 함수 add의 주소 대입
    printf("10 + 20 = %d\n", pf(10, 20));

    pf = sub; // 함수 add의 주소 대입
    printf("10 - 20 = %d\n", pf(10, 20));
}

함수 포인터를 모은 배열도 만들 수 있다.

c
#include <stdio.h>

// 함수 원형 정의
void menu() {
    printf("======================\n");
    printf("0. 덧셈\n");
    printf("1. 뺄셈\n");
    printf("2. 곱셈\n");
    printf("3. 나눗셈\n");
    printf("4. 종료\n");
    printf("======================\n");
};
int add(int x, int y){return x+y;}
int sub(int x, int y){return x-y;}
int mul(int x, int y){return x*y;}
int div(int x, int y){return x/y;}


int main() {
    int choice, result, x, y;
		// 함수 포인터 배열 선언 & 초기화
    int (*pf[4])(int, int) = {add, sub, mul, div};

    while (1) {
        menu();
        printf("메뉴를 선택하시오 -> ");
        scanf("%d", &choice);

        if (choice < 0 || choice > 4) {
            printf("다시 선택해주세요\n");
            continue;
        }
        else if (choice == 4) {
            break;
        }
        else {
            printf("2개의 정수를 입력하시오: ");
            scanf("%d %d", &x, &y);

            if(choice == 3 && y == 0) {
                printf("0으로 나눌 수는 없습니다.\n");
                continue;
            }

함수 포인터를 인수로 보내기

다음 식을 코딩하고, f(x)가 상황에 따라 달라질 수 있다고 해보자.

\sum~\{f(x)^2 + f(x) + 1\}
c
#include <stdio.h>
#include <math.h>

double f1(double k) {return 1.0 / k;}
double f2(double k) {return cos(k);}

double formula(double (*pf)(double), int n) {
// 함수 포인터를 매개변수로 받는다.
    double sum = 0.0;

    for(int i = 0; i < n; i++) {
        sum += pf(i) * pf(i) + pf(i) + 1;
    }
    return sum;
}

int main() {
    printf("%f\n", formula(f1, 10));
    printf("%f\n", formula(f2, 10));
}

다차원 배열과 포인터

c
#include <stdio.h>

int main() {
    int m[3][3] = { 10, 20, 30, 40, 50, 60, 70, 80, 90 };
    printf("m = %p\n", m);
    printf("m[0] = %p\n", m[0]);
    printf("m[1] = %p\n", m[1]);
    printf("m[2] = %p\n", m[2]);

    printf("m[0][0] = %p\n", &m[0][0]);
    printf("m[1][0] = %p\n", &m[1][0]);
    printf("m[2][0] = %p\n", &m[2][0]);
}
  • [10, 20, 30] → 0행
  • [40, 50, 60] → 1행
  • [70, 80, 90] → 2행

const와 volatile

c
const char *p;    // p가 가르키는 내용이 변경되지 않음을 나타냄
char const *p;    // 포인터 p가 변경되지 않음을 나타낸다.

volatile char *;  // p가 가리키는 내용이 수시로 변경되니 사용할 때마다 다시 로드.