programing

함수 포인터를 반환하는 함수에 대한 C 구문

muds 2023. 10. 3. 11:39
반응형

함수 포인터를 반환하는 함수에 대한 C 구문

다음과 같은 유형의 결함을 고려합니다.

typedef int (*f1)(float);
typedef f1 (*f2)(double);
typedef f2 (*f3)(int);

f2는 함수 포인터를 반환하는 함수입니다.입니다.f3 , , f3환, isf2할 수 ?f3유형의 결함 없이?다를 이 더 는 것을 알고 .f3C더 잘 하지만 여기서 나의 의도는 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로 변환하는지 이해하는 데 도움이 될 것입니다.

Function in function return value, recursively

먼저 (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

반응형