C++ 포인터 정리

mohadang·2023년 4월 15일
0

C++

목록 보기
45/48
post-thumbnail

포인터 해석 순서

이름 옆에 *, [], () 가 붙으면 포인터로 해석된다.
*[] 해석시 []가 먼저 해석 된다는 것을 주의해야 한다.
*() 해석시 ()가 먼저 해석 된다는 것을 주의해야 한다.

함수

#include <stdio.h>
void print_data(int data[][3]) {
  for (int i = 0; i < 5; ++i) {
    for (int j = 0; j < 3; ++j) {
      printf("%d\t", data[i][j]);      
    }
    puts("");
  }  
}

int main() {
  int data[5][3] = {0,};
  for (int i = 0; i < 5; ++i) {
    for (int j = 0; j < 3; ++j) {
      data[i][j] = i * 10 + j;
    }
  }

  print_data(data);
  return 0;
}

다차원 배열을 가르키는 포인터는 일반적으로 다음과 같이 끝에만 배열 길이를 둔다

int data[][3]

int data[][3] 해석

ptr 이다.

data[]

길이가 3인 X 타입 배열을 가리키는 ptr 이다

data[][3]

길이가 3인 int 타입 배열을 가리키는 ptr 이다

int data[][3]

이를 통해서 함수 시그치처를 다르게 표현할 수 있다. 다음과 같이 표현하면 될까 ?

void print_data(int *data[3])

결론부터 말하자면 X 이다.

int *data[3] 해석

길이가 3인 X 타입 원소 배열이다

`*` 보다 `[]`가 먼저 해석된다
data[3]

길이가 3인 X ptr 타입 원소 배열이다

*data[3]

길이가 3인 int ptr 타입 원소 배열이다

int *data[3]

제대로 표현하기 위해서는 ()를 사용하여 해석 우선 순위를 조정해야 한다.

void print_data(int (*data)[3])

int (*data)[3] 해석

ptr 이다.

(*data)

길이가 3인 X 타입 배열을 가리키는 ptr 이다

(*data)[3]

길이가 3인 int 타입 배열을 가리키는 ptr 이다

int (*data)[3]

배열

int main() {
  int data[3][3] = {0,};
  data[1][1] = 1;
  *(data[1] + 1) = 1;
  *(*(data + 1) + 1) = 1;
  (*(data + 1))[1] = 1;
  // *(data + 1)[1] = 1; // data[2][0], * 와 [] 우선 순위 주의 !!

  print_data(data);
  return 0;
}
red@DESKTOP-G15ND3V:~/workspace/test$ ./a.out 
0       0       0
0       1       0
0       0       0

주소에 산술 연산을 하면 주소의 길이만큼 메모리 점프를 한다.
이를 이용하여 다양한 방식으로 메모리에 있는 값을 참조 가능 하다.

함수 포인터

#include <stdio.h>

double foo(double x) {
  return 1.0 / x;
}

double sum_square(double func(double x), int m, int n) {
  int k;
  double sum = 0.0;
  for ( k = m; k <= n; ++k) {
    sum += (*func)(k) * (*func)(k);
    
    // 이렇게도 사용 가능, 알아서 역참조함. 단 비직관적일 수도...
    // sum += func(k) * func(k); 
  }
  return sum;
}

int main() {
  printf("%f\n", sum_square(foo, 2, 13));
  return 0;
}

double f(double x)는 함수 포인터이다.
함수 자체가 기본적으로 상수 포인터이다.

double foo(double x) 함수를 보면

foo()를 먼저 해석하게 됨으로 포인터이다
그 이후 인자가 double x, 반환값이 double로 해석한다.

같은 방식으로 double func(double x) 해석이 가능 할 것이다.
하지만 포인터인 것을 나타내기 위해 *를 조함하여 표현 가능 하다

이렇게 표현하면 어떻게 될까 ?
double *func(double x)
() 가 먼저 해석되어 반환 타입이 double* 인 함수 포인터가 된다

제대로 하려면 ()를 사용하여 우선 순위 조정 필요
double (*func)(double x)

함수 포인터 배열 예

#include <stdio.h>

double add1(double x) {
  return x + 1;
}
double add2(double x) {
  return x + 2;
}
double add3(double x) {
  return x + 3;
}

void add_combo(double (*func_arr[3])(double x), int m) {
  printf("%f\n", func_arr[0](m));
  printf("%f\n", func_arr[1](m));
  printf("%f\n", func_arr[2](m));
}

int main() {
  double (*func_arr[3])(double x) = { add1, add2, add3 };
  add_combo(func_arr, 0);
  return 0;
}

double (*func_arr[3])(double x) 를 해석하면

길이 3인 배열이다.

func_arr[3]

X ptr 타입 길이 3인 배열이다

(*func_arr[3])

double X(double x) ptr 타입 길이 3인 배열이다

`double (*func_arr[3])(double x)`
profile
mohadang

0개의 댓글