함수의 주소
다른 데이터 항목과 마찬가지로 정의된 함수는 메모리(텍스트 세그먼트)에 로드되고 프로그램이 실행될 때 주소를 갖습니다. 이 시점에서 함수의 이름은 실제로 함수의 시작 주소를 가리키는 상수 포인터입니다. 함수 이름과 같은 함수의 시작 주소에 대한 const 포인터. 함수 포인터그것은 말한다. 함수 포인터는 함수를 다른 함수의 인수로 전달할 때 유용합니다.
test(); 함수
test 함수의 주소 (즉, 함수를 지시하는 '함수 포인터')
함수 포인터 선언
포인터를 선언하려면 포인터가 가리키는 데이터 유형을 정확히 지정해야 합니다. 즉, 함수 포인터 선언은 함수의 반환 유형, 매개변수 수 및 데이터 유형을 전달해야 합니다.
double pam(int n); 함수 원형
double (*pa)(int); 함수 포인터
pa = pam;
함수 포인터 사용
함수 포인터를 선언하면 함수처럼 사용할 수 있습니다. 그러나 이것은 까다로운 일이 발생하는 곳입니다.
double x = pam(4); pam()은 함수, pam은 함수 포인터
double x = pa(4); pa()는 함수, pa는 함수 포인터. 그렇다면 *pa는??
pa는 함수 포인터이므로 함수는 *pa여야 합니다. 그러나 함수 이름은 함수 포인터로 간주되므로 함수 포인터 pa 자체를 함수 이름으로 사용할 수 있습니다. 즉, pa와 *pa는 모두 함수 이름(함수 포인터)과 동일한 의미를 갖습니다. 아래 코드는 동일한 명령 주소(기능)를 가지며 동일한 작업을 수행합니다.
double x = pam(4);
double x = pa(4);
double x = (*pa)(4)
함수 포인터 배열
함수 포인터는 다른 포인터처럼 배열을 만들 수 있습니다. 선언문은 다음과 같습니다.
double (*pb(3))(int); //연산자 우선순위는 ()가 *보다 높다.
*pb(3) 포인터의 배열
(*pb)(3) 원소 3개인 배열을 지시하는 포인터
배열, 포인터 및 함수 혼합
일반 데이터 유형의 배열, 포인터를 반환하는 함수, 해당 함수를 가리키는 함수 포인터, 함수 포인터 배열, 함수 포인터 배열을 가리키는 포인터. 다음 코드는 모두 동시에 사용할 것이기 때문에 조금 더 복잡해집니다. 이들의 관계를 잘 살펴보자.
//포인터를 그대로 반환하는 함수
const double* f1(const double*, int);
const double* f2(const double*, int);
const double* f3(const double*, int);
int main()
{
//배열
double a(3) = { 11.1, 22.2,33.3 };
//함수 포인터
const double* (*pa)(const double*, int) = f1;
//함수 포인터의 배열
const double* (*pb(3))(const double*, int) = { f1,f2,f3 };
//함수 포인터 배열을 가르키는 포인터
const double* (*(*pc)(3))(const double*, int) = &pb;
return 0;
}
pc는 함수 포인터의 배열을 가리키는 포인터입니다.
*pc는 함수 포인터의 배열입니다. B.pb. *pc == pb
따라서 (*pc)(0)은 함수 포인터입니다. (*pc)(0) == pb(0)
위 함수 포인터는 함수 이름으로 사용하기 때문에 생략하고 함수 이름으로 사용한다. 따라서 ((*pc)(0))은 위와 동일한 함수 포인터입니다. (개)(0) == pb(0) == ((*개)(0))
(*pc)(0)은 함수 f1을 가리키는 함수 포인터입니다. (pc)(0) == ((*pc)(0)) == pb(0) == f1
(*pc)(0)(a, 3)은 배열 a의 주소를 반환합니다. (*pc)(0)(a, 3) == f1(a,3)
((*pc)(0)(a, 3))(2)는 배열 a의 세 번째 요소인 33.3입니다.
보시다시피 함수 포인터는 복잡하고 불편하기 때문에 auto 또는 typedef 자동 데이터 유형을 자주 사용합니다.
