source

C의 함수 내부의 함수

manysource 2023. 10. 17. 20:22

C의 함수 내부의 함수

나는 이것과 비슷한 코드를 만들고 있습니다.

#include <stdio.h>

double some_function( double x, double y)
{
  double inner_function(double x)
  { 
    // some code
    return x*x;
  }

  double z;
  z = inner_function(x);
  return z+y;

}

int main(void)
{
  printf("%f\n", some_function(2.0, 4.0));
  return 0;
}

이것은 GCC에서 완벽하게 컴파일되지만(경고 없이) ICC에서는 컴파일되지 못합니다.

ICC는 다음을 제공합니다.

main.c(16): error: expected a ";"
    { 
    ^

main.c(21): warning #12: parsing restarts here after previous syntax error
    double z;
            ^

main.c(22): error: identifier "z" is undefined
    z = inner_function(x);
    ^

compilation aborted for main.c (code 2)

내가 뭘 잘못하고 있는 거지?

감사해요.

(편집) 실례를 범해서 죄송합니다.원래 내 코드에서 나는 이것을 해야합니다.저는 GSL 수치 적분기를 사용하고 있으며 다음과 같은 것이 있습니다.

double stuff(double a, double b)
{
  struct parameters
  {
    double a, b;
  };

  double f(double x, void * params)
  {
    struct parameters p = (struct parameters *) params;
    double a = p->a, b = b->b;
    return some_expression_involving(a,b,x);
  }
  struct parameters par = {a,b};

  integrate(&f, &par);

}

저는 이런 종류의 구조를 가진 많은 기능들을 가지고 있습니다. 그것들은 많은 외부 매개변수들과 기능들의 통합의 결과입니다.그리고 수치 적분을 구현하는 함수는 다음과 같은 형태의 함수에 대한 포인터를 받아야 합니다.

double f(double x, void * par)

함수들을 이런 식으로 중첩해서 많은 함수들로 코드가 부풀어 오르지 않게 했으면 좋겠습니다.그리고 ICC와 함께 컴파일을 해서 좀 더 속도를 낼 수 있었으면 좋겠습니다.

중첩 함수는 GCC에서 언어 확장으로 사용할 수 있지만 표준 언어의 일부가 아니므로 일부 컴파일러에서는 사용할 수 없습니다.

다른 모든 사람들은 표준 C에서는 네스팅 함수가 허용되지 않습니다라는 표준적인 답을 당신에게 주었습니다. (따라서 그 함수들의 어떤 사용도 당신의 컴파일러에 달려있습니다.)

수정된 예는 다음과 같습니다.

double stuff(double a, double b)
{
  struct parameters
  {
    double a, b;
  };

  double f(double x, void * params)
  {
    struct parameters p = (struct parameters *) params;
    double a = p->a, b = b->b;
    return some_expression_involving(a,b,x);
  }
  struct parameters par = {a,b};

  return integrate(&f, &par);     // return added!
}

인테그레이터 등의 기능이 필요하다고 말씀하셨기 때문에

  double (*f)(double x, void * par);

왜 굳이 중첩 기능이 필요한지 전혀 모르겠습니다.나는 다음과 같은 글을 쓸 것으로 예상합니다.

struct parameters
{
    double a, b;
};

static double f(double x, void *params)
{
    struct parameters p = (struct parameters *) params;
    double a = p->a, b = b->b;
    return some_expression_involving(a,b,x);
}

double stuff(double a, double b)
{
    struct parameters par = { a, b };
    return integrate(f, &par);
}

위의 코드는 C89('par'를 초기화하는 데 문제가 없는 한) 또는 C99에서 작동해야 합니다. 이 버전의 코드는 파라미터에 복합 리터럴을 사용하는 C99 전용입니다(섹션 6.5.2.5 복합 리터럴):

double stuff(double a, double b)
{
    return integrate(f, &(struct parameters){a, b});
}

'구조 모수' 유형에 대한 변형이 몇 가지에 불과할 가능성이 높습니다.다양한 함수에 대해 별도의 의미 있는 이름을 지정해야 합니다. '라는 하나의 함수만 가질 수 있습니다.f' 소스 파일당.

중첩 함수 버전의 유일한 한계 작은 이점은 다음과 같은 다른 함수가 없다는 것입니다.stuff부름f. 그러나 예제 코드를 고려할 때 그것은 주요 이점이 아닙니다; 정적 정의f함수에 대한 포인터를 전달하지 않는 한 이 파일 외부의 어떤 함수도 호출할 수 없음을 의미합니다.

C에는 중첩 함수가 없습니다.GCC의 중첩 기능은 언어의 확장입니다.

GCC의 런타임 오류는 철자 오류입니다.inner_funcion그래야 한다inner_function.

위의 많은 답변들이 언급한 바와 같이, C에서는 내부 기능이 지원되지 않습니다.그러나 C++에서는 내부 클래스를 사용하여 유사한 작업을 수행할 수 있습니다.유감스럽게도, 그것들은 사용하기에 다소 무리가 있지만, C++로 컴파일하는 것을 개의치 않는다면 당신에게 선택 사항이 될 수도 있습니다.

검증되지 않은 예:

double some_function( double x, double y)
{
  struct InnerFuncs
  {
    double inner_function(double x)
    { 
      // some code
      return x*x;
    }
    // put more functions here if you wish...
  } inner;

  double z;
  z = inner.inner_function(x);
  return z+y; 
}

이 대답이 당신이 보여준 사용법에서 내부 기능이 좋은 아이디어라고 생각한다는 것을 의미하는 것은 아닙니다.

몇 년 후 편집:

이제 C++는 내부 기능으로 람다를 사용할 수 있게 되었습니다.위의 나의 장난감 예제의 경우, 다음과 같이 보일 것입니다.

double some_function( double x, double y)
{
   auto inner_function = [&]() { return x * x; }
   
   double z;
   z = inner_function ();
   return z + y;
}

국소 변수 x는 람다 내부에 자동으로 포획되며, 이는 매우 좋은 특징입니다.

자세한 내용:C++11의 람다 표현은 무엇입니까?

중첩 함수를 사용하고 있습니다. C는 이러한 함수를 지원하지 않습니다.

이 코드는 유효하지 않습니다. 내부 함수는 C에서 지원되지 않습니다.

함수 내부의 로컬 함수 정의는 C에서 불법입니다.

중첩 함수는 C 표준의 일부가 아닙니다.따라서 모든 컴파일러에 대해 작동한다는 보장은 없으며 반드시 피해야 합니다.

이벤트에서 GCC 확장 기능을 끄는 방법 등에 대해 궁금하셨을 경우.

사용할 수 있습니다.-ansi플래그는 기본적으로 표준을 c89로 설정하고 ISO C90과 호환되지 않는 GCC 기능을 끕니다.

자세한 내용은 문서를 참조하십시오.확인해보세요.-std깃발도.

전문가는 아니지만, C99 사양에서는 이것이 명시적으로 허용되지 않거나 정의되지 않았기 때문에 멀리하는 것이 최선일 것입니다.

언급URL : https://stackoverflow.com/questions/957592/functions-inside-functions-in-c