함수 포인터를 반환하는 함수에 대한 C 구문
다음과 같은 유형의 결함을 고려합니다.
typedef int (*f1)(float);
typedef f1 (*f2)(double);
typedef f2 (*f3)(int);
f2
는 함수 포인터를 반환하는 함수입니다.입니다.f3
, , f3
환, isf2
할 수 ?f3
유형의 결함 없이?다를 이 더 는 것을 알고 .f3
C더 잘 하지만 여기서 나의 의도는 C 구문을 더 잘 이해하는 것입니다.
합니다 합니다.f1
:
int (*f1)(float);
너는 원한다f2
.f1
대신에, ㅇf1
에서 에.f2
:
int (* f1 )(float);
|
+-----+-----+
| |
v v
int (*(*f2)(double))(float);
선언문에는 다음과 같이 적혀 있습니다.
f2 -- f2
*f2 -- is a pointer
(*f2)( ) -- to a function
(*f2)(double) -- taking a double parameter
*(*f2)(double) -- returning a pointer
(*(*f2)(double))( ) -- to a function
(*(*f2)(double))(float) -- taking a float parameter
int (*(*f2)(double))(float) -- returning int
다음에 대한 프로세스를 반복합니다.f3
:
int (*(* f2 )(double))(float);
|
+---+----+
| |
v v
int (*(*(*f3)(int))(double))(float);
라고 쓰여져 있습니다.
f3 -- f3
*f3 -- is a pointer
(*f3)( ) -- to a function
(*f3)(int) -- taking an int parameter
*(*f3)(int) -- returning a pointer
(*(*f3)(int))( ) -- to a function
(*(*f3)(int))(double) -- taking a double parameter
*(*(*f3)(int))(double) -- returning a pointer
(*(*(*f3)(int))(double))( ) -- to a function
(*(*(*f3)(int))(double))(float) -- taking a float parameter
int (*(*(*f3)(int))(double))(float); -- returning int
C++에서는 템플릿의 기적이 이를 좀 더 쉽게 만들 수 있습니다.
#include <type_traits>
std::add_pointer<
std::add_pointer<
std::add_pointer<
int(float)
>::type(double)
>::type(int)
>::type wow;
typedef와 동일하게 함수 정의를 이름 대신에 배치합니다.
!f2
다음과 같습니다.
typedef int (*(*f2)(double))(float);
할수있습니다f3
때문에 에,으로;)
그냥 하지 마.할 수는 있지만, 매우 혼란스러울 것입니다.타이디프는 이 짧은 코드를 쉽게 쓰고 읽을 수 있는 기능이 있습니다.
A f
하지 않고 합니다를 합니다.int (*)(float)
아마 (검증되지 않은) 다음과 같은 것이 될 것입니다.
int (*f())(float);
그러면 나머지는 계속 괄호만 붙이면 입 모양이 될 때까지.
오른쪽 왼쪽 규칙을 배웁니다.
"우-좌" 규칙은 C 선언을 해독하기 위한 완전히 규칙적인 규칙입니다.그것은 또한 그것들을 만들 때 유용할 수 있습니다.
존 보드의 답변에서 영감을 얻어 그래픽으로 표현하고자 합니다.컴파일러가 어떻게 AST로 변환하는지 이해하는 데 도움이 될 것입니다.
먼저 (1) "typedef f2(*f3)(int);"로 표시되는 포장된 유형 f3부터 시작합니다.그 자체로 기능 유형입니다.그런 다음 (2)에서 한 단계 더 열려서, 기본적으로 C 언어의 "is-function" CFG 제작을 수행합니다(저는 독자가 프로그래밍 언어 어휘 분석에 대한 기본적인 생각을 가지고 있다고 가정합니다).(3)을 보면, 우리가 "is-function" 어휘화 단계를 세 번 재귀적으로 수행한 것을 알 수 있고, 그 세 번은 그래프의 "function" 노드에 의해 볼 수 있습니다.
맞춤 표기법으로 필요한(단순화된) CFG 생산을 시도해보면...
declaration -> underlying_type:specifier sp ( func-ptr-decl | specifier )
func-ptr-decl -> '(' sp '*' sp ( func-ptr-decl | specifier ) sp ')' sp '(' sp param-list sp ')'
specifier는 C 프로그래밍 언어에서 변수 이름으로 가장 잘 설명되는 문자의 문자열이며, 공백 문자열(선택 사항)이고, param-list는 쉼표로 구분된 선언 목록으로 단순화됩니다.
C에서는 변수나 매개 변수를 도입하는 각 문을 선언이라고 합니다.선언은 위치/이름, 데이터 유형 및 이니셜라이저로 구성됩니다.주어진 질문에서 우리는 함수에 대한 포인터 형태의 선언을 가지고 있습니다.포인터 대 함수 유형은 최대 세 번까지 재귀적으로 중첩됩니다.그래프는 화살표가 다른 유형 내부에 둥지를 틀고 있음을 의미하는 유형을 가리키는 방식으로 보여줍니다.
사용하다std::function
:
typedef std::function<int(float)> f1;
typedef std::function<f1(double)> f2;
typedef std::function<f2(int)> f3;
아니면
typedef std::function<std::function<std::function<int(float)>(double)>(int)> f3;
언급URL : https://stackoverflow.com/questions/10758811/c-syntax-for-functions-returning-function-pointers
'programing' 카테고리의 다른 글
주문 업데이트를 위한 우커머스 후크 (0) | 2023.10.03 |
---|---|
주 번호에서 날짜 가져오기 (0) | 2023.10.03 |
팬더 - 값 없음 필터링 (0) | 2023.10.03 |
PL/SQL에서 돌아오는 커서를 닫는 방법은? (0) | 2023.10.03 |
브라우저 콘솔에서 http 오류가 기록되지 않도록 방지 (0) | 2023.10.03 |