2010-06-30 32 views
5

Böyle bir şey C de mümkün mü?C, fonksiyon göstergeleri ile argümanlar önceden ayarlanmış

#include <stdio.h> 

void print_str(char *str) { 
     printf(str); 
} 

int main() { 

     void (*f_ptr)() = print_str,"hello world"; 

     f_ptr(); 

} 

//see "hello world" on stdout 

Özetle, bağımsız değişkenleri "saklayan" bir işlev işaretçisine sahip olmak isterim. Asıl nokta, fonksiyon göstergesinin, orijinal verilere bir referansa gerek kalmaksızın daha sonra kullanılabileceğidir.

Ben çifte bir işlev işaretçisi ve bir argüman referansı

struct f_ptr { 
void (*f)(); 
void *data; 
} 

void exec_f_ptr(f_ptr *data) { 
    data->f(data->data): 
} 

böyle bir şey kullanabilirsiniz ama sadece içeride bağımsız değişkenle bir işlev işaretçisi çağırarak kadar zarif olmaz.

+1

Yanlış bir dil kullanıyorsunuz. İkinci çözüm genellikle C.'de kullanılan şeydir. Farklı işaretlerle işlev göstergelerini alamayız ve hepsini aynı kod aracılığıyla çağırmaya çalışamayız. C++ daha fazla imkanlara sahiptir ve bunun için daha uygundur, fakat dinamik sınıflandırma ve birinci sınıf nesneler olarak işlev gösteren komut dosyaları, genellikle bu tür kodlar için en uygun olanlardır. – stinky472

+0

Bir makro # #define DO_FUN (d) (d) -> f ((d) -> veri) 'yi tanımlayabilirsiniz, sonra argüman ile bir işaretçiyi çağırmak için bir satırınızı 'DO_FUN (veri); – maxwellb

+0

Oh, exec işleviyle yaptığınız şey bu, şimdi görüyorum? Bu durumda herkes haklı, bu sahip olduğun en iyisi. – maxwellb

cevap

3

almak için gidiyoruz olduğunu - "nesnesi" yani veri ve kod tek yer Bu tür nesneler standart C'de mevcut değildir - Apple'ın bloklarından veya diğer dillerdeki anonim işlevlerden (veya bunları destekleyen dillerde açık olan kapaklardan) benzer bir şey elde edebilirsiniz, ancak genel olarak bazı veri türlerini oluşturmanız gerekecek keşfettiğin gibi.

+0

Bu yapının, Uygulama işaretçisi ve argümanının büyük bir uygulaması için, DIKU ve ROM MUD'larının bir çok işlev için bu yapı yapısından geçtiğine inanıyorum. – maxwellb

0

Hayır, bu yapı en yakın şey Temelde bir kapatma yerine bir işlev işaretçisi için soruyorsun

4

Ne istiyorsan closure veya curried function. Ne yazık ki, C bunların ikisine de sahip değil. (Apple, C sürümünde introduce closures'u kullandı ve umarız dilin gelecekteki bir sürümü için benimsenir, ancak bu C99'un bir parçası değildir.)

+0

Curried işlevi kapanıyor mu? – Tyler

1

GLib, özellikle sinyal geri dönüşleri için kullanılan support for closures ürününe sahiptir. Çapraz platform ve bir göz atmaya değer olabilir (gereksinimlerinize bağlı olarak). (Ayrıca bkz. GLib closure API.)

+0

İlginç olsa da, C'deki kapanışları istediğiniz normal yer, bir bağlamı kendiliğinden geçirme yeteneğini ortadan kaldıran eski API'lerle kullanmak olduğu için, bu muhtemelen çok kullanışlı değildir. Örneğin, qsort() işlevini kullanmak istiyorsanız, ancak Karşılaştırma bir parametreye bağlıdır ve her biri için farklı bir işlev yapamayacağınız yeterli parametreler vardır. –

İlgili konular