C의 중첩 함수


95

C에서 중첩 함수를 가질 수 있습니까? 중첩 함수의 사용은 무엇입니까? C에 존재한다면 컴파일러마다 구현이 다른가요?


1
중복되는 것 같습니다 : stackoverflow.com/questions/1348095/…
zoli2k 2010

답변:



36

아니요, C에는 존재하지 않습니다.

Pascal과 같은 언어에서 사용되는 이유는 최소한 두 가지입니다.

  1. 네임 스페이스를 오염시키지 않고 기능적 분해를 허용합니다. 하나 이상의 중첩 함수를 사용하여 문제를 더 작은 논리적 조각으로 나눔으로써 복잡한 논리를 구현하는 공개적으로 표시되는 단일 함수를 정의 할 수 있습니다.
  2. 일부 경우 매개 변수 전달을 단순화합니다. 중첩 함수는 외부 함수 범위에있는 모든 매개 변수와 일부 또는 모든 변수에 액세스 할 수 있으므로 외부 함수는 로컬 상태 더미를 중첩 함수에 명시 적으로 전달할 필요가 없습니다.

21

중첩 된 기능의 일부가 아닌 ANSI C 그러나, 그들은의 일부 GNU C .


그들은 GNU C의 일부인 경우가 의미가 무엇입니까
Sachin Chourasiya

4
@Sachin 중첩 함수가있는 C 코드를 gcc로 컴파일 할 수있는 이유를 이해하는 데 도움이됩니다. 정보에는 교육적 가치가 있습니다. 또한 질문이 C89, C99 또는 GNU C로만 제한되는지 여부는 명시되지 않았습니다.
zoli2k 2010

4
GCC에서 지원하는 다른 언어에는 (ADA 및 Pascal)이 있으므로 C 구현에 추가하기 쉬웠거나 지원 언어를 준비하기 위해 C에 추가했을 가능성이 높습니다. 그들을 요구하십시오.
nategoose 2010

MATLAB에는 중첩 함수도 있습니다.
mikeTronix

17

아니요 .NET에서 중첩 된 함수를 가질 수 없습니다 C. 가장 가까운 방법은 다른 함수의 정의 안에 함수를 선언하는 것입니다. 하지만 그 함수의 정의는 다른 함수 본문 외부에 나타나야합니다.

void f(void)
{
    // Declare a function called g
    void g(void);

    // Call g
    g();
}

// Definition of g
void g(void)
{
}

6
함수 g가 이런 식으로 선언되면 그 범위는 무엇입니까?
Sachin Chourasiya 2010

6
선언은 다른 선언과 같이 범위가 지정되므로이 경우 함수가 끝날 때까지입니다. 물론 정의 g가 나중에 파일에서 표시되면 선언이 나머지 번역 단위의 범위에 포함됩니다. 또한 바람직하지 않은 경우에도 범위에서 보이는 선언없이 C에서 함수를 호출 할 수 있습니다 .
CB Bailey

5

C로 코딩하는 많은 사람들이 이제 C ++ 컴파일러 (예 : Visual C ++ 및 Keil uVision)를 사용하고 있으므로 이것을 사용할 수 있다고 언급했습니다.

아직 C에서 허용되지는 않지만 C ++를 사용하는 경우 C ++ 11에 도입 된 람다 함수를 사용하여 동일한 효과를 얻을 수 있습니다.

void f()
{
    auto g = [] () { /* Some functionality */ }

    g();
}

4
질문은 C ++가 아닌 C에 관한 것이 었습니다
Virgile 2014-06-25

11
@Virgile-질문에는 "다른 언어에서도 중첩 된 함수가 허용됩니까?"라고 구체적으로 명시되어 있습니다. Jon의 대답이 도움이되었습니다.
www-0av-Com 2015

3

다른 사람들이 대답했듯이 표준 C는 중첩 함수를 지원하지 않습니다.

일부 언어에서는 중첩 함수를 사용하여 여러 함수와 변수를 컨테이너 (외부 함수)로 묶어 개별 함수 (외부 함수 제외)와 변수가 외부에서 보이지 않도록합니다.

C 에서는 이러한 함수를 별도의 소스 파일에 넣어이를 수행 할 수 있습니다. 주 함수를 전역으로 정의하고 다른 모든 함수와 변수를 정적 으로 정의합니다 . 이제이 모듈 외부에는 주 기능 만 표시됩니다.


재귀가 있으면 outer-> nested-> outer->를 nested보유하는 두 개의 다른 프레임이 int declared_in_outer있으므로 declared_in_outer정적 전역으로 넣을 수 없습니다 .
Adrian Panasiuk 2013

1

두 번째 질문에 답하기 위해 중첩 함수를 정의 할 수있는 언어가 있습니다 (목록은 여기에서 찾을 수 있습니다 : nested-functions-language-list-wikipedia ).

가장 유명한 언어 중 하나 인 JavaScript에서 중첩 함수 (클로저라고 함) 중 하나는 다음과 같습니다.

  • 객체 생성자에서 클래스 메서드를 생성합니다.
  • setter 및 getter와 함께 private 클래스 멤버의 기능을 수행합니다.
  • 전역 네임 스페이스를 오염시키지 마십시오 (물론 모든 언어에 적용됩니다).

몇 가지 예를 들면 ...


0

또는 그것에 대해 현명하고 유리하게 전처리기를 사용할 수 있습니다 ( source.c) :

#ifndef FIRSTPASS
#include <stdio.h>

//here comes your "nested" definitions
#define FIRSTPASS
#include "source.c"
#undef FIRSTPASS

main(){
#else
    int global = 2;
    int func() {printf("%d\n", global);}
#endif
#ifndef FIRSTPASS
    func();}
#endif

-1

이것은 C의 중첩 함수가 아닙니까? (displayAccounts () 함수)

나는 함수를 다르게 정의하고 변수를 전달할 수 있었지만 계정을 여러 번 인쇄해야했기 때문에 어쨌든 잘 작동한다는 것을 알고 있습니다.

(학교 과제에서 가져온 스 니펫) ...

//function 'main' that executes the program.
int main(void)
{
    int customerArray[3][3] = {{1, 1000, 600}, {2, 5000, 2500}, {3, 10000, 2000}};  //multidimensional customer data array.
    int x, y;      //counters for the multidimensional customer array.
    char inquiry;  //variable used to store input from user ('y' or 'n' response on whether or not a recession is present).

    //function 'displayAccounts' displays the current status of accounts when called.
    void displayAccounts(void)
    {
        puts("\t\tBank Of Despair\n\nCustomer List:\n--------------");
        puts("Account #    Credit Limit\t  Balance\n---------    ------------\t  -------");
        for(x = 0; x <= 2; x++)
        {
            for(y = 0; y <= 2; y++)
                printf("%9d\t", customerArray[x][y]);
            puts("\n");
        }
    }

    displayAccounts();  //prints accounts to console.
    printf("Is there currently a recession (y or n)? ");


//...

    return 0;
}

4
합법적 인 표준 C가 아닙니다. 컴파일러에서 작동한다면 컴파일러가 표준 C 언어에 대한 확장을 제공했기 때문입니다. 어떤 의미에서 컴파일러는 엄격하게, C를하지 말이며, 다른 언어를 컴파일
네이트 엘 드리지

귀하의 의견에 감사드립니다. 그 이후로 함수를 선언, 정의 및 사용하는 적절한 방법을 배웠습니다. >. <
midnightCoder

1
@midnightCoder : 당신은 항상 당신의 대답 : 삭제할 수 있습니다
chqrlie
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.