이름 옆에 *
, []
, ()
가 붙으면 포인터로 해석된다.
*
와 []
해석시 []
가 먼저 해석 된다는 것을 주의해야 한다.
*
와 ()
해석시 ()
가 먼저 해석 된다는 것을 주의해야 한다.
#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]
ptr 이다.
data[]
길이가 3인 X 타입 배열을 가리키는 ptr 이다
data[][3]
길이가 3인 int 타입 배열을 가리키는 ptr 이다
int data[][3]
이를 통해서 함수 시그치처를 다르게 표현할 수 있다. 다음과 같이 표현하면 될까 ?
void print_data(int *data[3])
결론부터 말하자면 X 이다.
길이가 3인 X 타입 원소 배열이다
`*` 보다 `[]`가 먼저 해석된다
data[3]
길이가 3인 X ptr 타입 원소 배열이다
*data[3]
길이가 3인 int ptr 타입 원소 배열이다
int *data[3]
제대로 표현하기 위해서는 ()
를 사용하여 해석 우선 순위를 조정해야 한다.
void print_data(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)`