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
'source' 카테고리의 다른 글
Mono가 비어있는지 확인하는 방법은? (0) | 2023.10.17 |
---|---|
JS를 사용하여 이름 이니셜 가져오기 (0) | 2023.10.17 |
공백 문자를 모두 바꿉니다. (0) | 2023.10.17 |
Oracle: 행 유형 데이터를 다른 테이블에 삽입합니다. (0) | 2023.10.17 |
세션이 만료되면 .Net MVC 부분 보기 로드 로그인 페이지 (0) | 2023.10.17 |