Fungsi bersarang di C


96

Bisakah kita memiliki fungsi bersarang di C? Apa gunanya fungsi bertingkat? Jika mereka ada di C apakah implementasinya berbeda dari kompilator ke kompilator?


1
Tampaknya merupakan duplikat dari: stackoverflow.com/questions/1348095/…
zoli2k

Jawaban:



36

Tidak, mereka tidak ada di C.

Mereka digunakan dalam bahasa seperti Pascal karena (setidaknya) dua alasan:

  1. Mereka memungkinkan dekomposisi fungsional tanpa mencemari namespace. Anda dapat menentukan satu fungsi yang dapat dilihat publik yang mengimplementasikan beberapa logika kompleks dengan mengandalkan satu atau beberapa fungsi bertingkat untuk memecah masalah menjadi bagian yang lebih kecil dan logis.
  2. Mereka menyederhanakan penerusan parameter dalam beberapa kasus. Fungsi bertingkat memiliki akses ke semua parameter dan beberapa atau semua variabel dalam cakupan fungsi luar, sehingga fungsi luar tidak harus secara eksplisit meneruskan tumpukan status lokal ke dalam fungsi bertingkat.

21

Fungsi bersarang bukan merupakan bagian dari ANSI C , bagaimanapun, mereka adalah bagian dari Gnu C .


Apa pentingnya jika mereka adalah bagian dari Gnu C
Sachin Chourasiya

4
@Sachin Membantu menyadari mengapa kode C dengan fungsi bersarang dapat dikompilasi dengan gcc. Informasi tersebut memiliki nilai pendidikan. Selain itu, pertanyaan tidak ditentukan apakah hanya terbatas pada C89, C99 atau GNU C
zoli2k

4
Bahasa lain yang didukung oleh GCC memang memilikinya (ADA dan Pascal yang saya ketahui), jadi kemungkinan besar mudah untuk menambahkan implementasi C atau ditambahkan ke C untuk mempersiapkan bahasa pendukung yang membutuhkan mereka.
nategoose

MATLAB juga memiliki fungsi bersarang.
mikeTronix

17

Tidak, Anda tidak dapat memiliki fungsi bertingkat di C . Hal terdekat yang bisa Anda lakukan adalah mendeklarasikan suatu fungsi di dalam definisi fungsi lain. Definisi fungsi itu harus muncul di luar badan fungsi lainnya.

Misalnya

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

    // Call g
    g();
}

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

6
Jika fungsi g dideklarasikan dengan cara ini, lalu apa cakupannya?
Sachin Chourasiya

6
Deklarasi tersebut memiliki cakupan seperti deklarasi lainnya, jadi dalam kasus ini hingga akhir fungsi. Tentu saja setelah definisi gterlihat nanti di file deklarasi itu berada dalam cakupan unit terjemahan lainnya. Selain itu, Anda dapat memanggil fungsi di C tanpa deklarasi yang terlihat dalam cakupan meskipun tidak disarankan.
CB Bailey

5

Saya menyebutkan ini karena banyak orang yang mengkodekan dalam C sekarang menggunakan kompiler C ++ (seperti Visual C ++ dan Keil uVision) untuk melakukannya, jadi Anda mungkin dapat memanfaatkan ini ...

Meskipun belum diizinkan di C, jika Anda menggunakan C ++, Anda dapat memperoleh efek yang sama dengan fungsi lambda yang diperkenalkan di C ++ 11:

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

    g();
}

4
Pertanyaannya secara khusus tentang C, bukan C ++
Virgile

11
@Virgile - Dan pertanyaannya juga secara khusus menyatakan "Apakah fungsi bertingkat diperbolehkan dalam bahasa lain?". Jawaban Jon membantu saya.
www-0av-Com

3

Seperti yang telah dijawab orang lain, C standar tidak mendukung fungsi bertingkat.

Fungsi bersarang digunakan dalam beberapa bahasa untuk memasukkan beberapa fungsi dan variabel ke dalam wadah (fungsi luar) sehingga fungsi individu (tidak termasuk fungsi luar) dan variabel tidak terlihat dari luar.

Di C , ini dapat dilakukan dengan meletakkan fungsi-fungsi seperti itu dalam file sumber terpisah. Tentukan fungsi utama sebagai global dan semua fungsi serta variabel lainnya sebagai statis . Sekarang hanya fungsi utama yang terlihat di luar modul ini.


Jika ada rekursi outer-> nested-> outer-> nested, maka akan ada dua penahan frame yang berbeda int declared_in_outer, jadi Anda tidak bisa hanya menempatkan declared_in_outersebagai global statis.
Adrian Panasiuk

1

Untuk menjawab pertanyaan kedua Anda, ada bahasa yang memungkinkan untuk menentukan fungsi bertingkat (daftarnya dapat ditemukan di sini: nested-functions-language-list-wikipedia ).

Dalam JavaScript, yang merupakan salah satu bahasa yang paling terkenal, salah satu dari fungsi bersarang (yang disebut closures) adalah:

  • Untuk membuat metode kelas dalam konstruktor objek.
  • Untuk mencapai fungsionalitas anggota kelas privat bersama dengan setter dan getter.
  • Tidak mencemari namespace global (yang berlaku untuk setiap bahasa, tentu saja).

untuk beberapa nama ...


0

Atau Anda bisa pintar tentang itu dan menggunakan preprocessor untuk keuntungan Anda ( 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

apakah ini bukan fungsi bersarang di C? (fungsi displayAccounts ())

Saya tahu saya dapat mendefinisikan fungsi secara berbeda dan meneruskan variabel dan apa yang tidak, tetapi bagaimanapun, berfungsi dengan baik karena saya perlu mencetak akun beberapa kali.

(snipet diambil dari tugas sekolah) ...

//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
Ini bukan standar hukum C. Jika bekerja dengan kompilator Anda, itu karena kompilator Anda telah menyediakan ekstensi ke bahasa C standar; dalam beberapa hal, kompilator Anda mengompilasi bahasa yang berbeda, yang sebenarnya, bukan C.
Nate Eldredge

Terima kasih atas masukannya. Saya telah mempelajari cara yang tepat untuk mendeklarasikan, mendefinisikan dan menggunakan fungsi. ini agak memalukan untuk dilihat kembali>. <
midnightCoder

1
@midnightCoder: Anda selalu dapat menghapus jawaban Anda :)
chqrlie
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.