C parametresi olarak işlev görür

Şu anda int C sınıfından bir proje üzerinde çalışıyorum, temel olarak C'de bir karma tablo uygulaması yaratıyoruz, ancak şu andaki sorumum profesörüm tarafından sağlanan kod iskeletinde belirli bir fonksiyonun nasıl yazıldığına ilişkin. İşte create metodunun başlık tanımı:

     Table* create(long (*hash)(void* key),
          bool (*equals)(void* key1, void* key2),
          void (*print)(void* key1, void* key2));

Bu parametre olarak fonksiyon işaretçiler gibi görünüyor? Bunu nasıl arayacağımı bile bilmiyorum, ya da aradığında ne olacağını bilemiyorum. Bu yöntemlerin (karma, eşit ve baskı) nereden geldiğinden bile emin değilim. Herhangi bir yardım büyük takdir edilecektir. Teşekkürler

1
Bir işleve veya diziye bir göstericiniz varsa, seçeneğiniz olduğunda her zaman bir typedef kullanın. Bu durumda olmayabilir, ancak böyle bir kaos gördüğünüzde bir dahaki sefere aklınızda bulundurun.
katma yazar Mooing Duck, kaynak

8 cevap

Evet, bu, üç işlev işaretçisini argüman olarak alan ve bir işaretçiyi Tabloya döndüren bir işlevdir. Kullanmak için, verilen kriterleri karşılayan üç fonksiyon tanımlamanız gerekir:

long my_hash(void *key) { ... }
bool my_equals(void *key1, void *key2) { ... }
void my_print(void *key1, void *key2) { ... }

ve ardından fonksiyonu onlarla çağırın:

t = create(my_hash, my_equals, my_print);

Bu bir karma tablo oluşturma amaçlı gibi görünüyor ve ona bir karma işlevi ve karşılaştırma işlevi vermeniz gerekiyor. Yazdırma işlevi muhtemelen sadece hata ayıklama içindir.

2
katma

Evet, bu, üç işlev işaretçisini argüman olarak alan ve bir işaretçiyi Tabloya döndüren bir işlevdir. Kullanmak için, verilen kriterleri karşılayan üç fonksiyon tanımlamanız gerekir:

long my_hash(void *key) { ... }
bool my_equals(void *key1, void *key2) { ... }
void my_print(void *key1, void *key2) { ... }

ve ardından fonksiyonu onlarla çağırın:

t = create(my_hash, my_equals, my_print);

Bu bir karma tablo oluşturma amaçlı gibi görünüyor ve ona bir karma işlevi ve karşılaştırma işlevi vermeniz gerekiyor. Yazdırma işlevi muhtemelen sadece hata ayıklama içindir.

2
katma

Bu, parametre olarak işlevler için işaretçiler olarak görünüyor?

Evet.

Bunu nasıl arayacağımı bile bilmiyorum

create işlevini çağırmak için, bazı işlevlerin adreslerini create olarak adlandırmak için doğru türlerle iletin:

create(&f1, &f2, &f3);

veya arandığında ne olur?

create 'nin gövdesindeki herhangi bir yer, (*) sivri işlevi çağrılır, asıl işlev (örneğin f1 ) verilen argümanlarla çağrılır. create içinde gerçekleşmiş kurgusal bir örnek olarak (* eşittir) (k1, k2); olabilir.

(*) veya, bu durumda, işlevi create tarafından tahsis edilen yapıdan işaretçilerine getirecek başka bir işlev onları depolar.


Aslında C, ilk önce create (f1, f2, f3); ve ikinci olarak (k1, k2); 'a eşittir; Kolaylık.

2
katma
@DanielMoody İşlev imleçleri C’de gariptir, çünkü her iki yönde de otomatik olarak dönüştürürler. Bunu sana söylemem gerekip gerekmediğini bilmiyorum ama 4. örneğe cs.berkeley.edu/~necula/cil/cil016.html . Her neyse, create (& f1…/(* eşittir) (k1… ve create (f1…/equals (k1… ) arasında rahat edeceğiniz bir stil seçin buna bağlı kalın, ancak bir işlev veya işlev işaretçisi için bir & veya bir * unu unuttuğunuzda derleyici uyarıları almazsanız şaşırmayın.
katma yazar Pascal Cuoq, kaynak
Evet, teşekkür ederim bu çok daha anlamlı. Bu görüntünün sözdizimi öyle garip ki, onunla ne yapacağımı, hatta nasıl bakacağımı bile bilmiyordum.
katma yazar Daniel Moody, kaynak

Bu, parametre olarak işlevler için işaretçiler olarak görünüyor?

Evet.

Bunu nasıl arayacağımı bile bilmiyorum

create işlevini çağırmak için, bazı işlevlerin adreslerini create olarak adlandırmak için doğru türlerle iletin:

create(&f1, &f2, &f3);

veya arandığında ne olur?

create 'nin gövdesindeki herhangi bir yer, (*) sivri işlevi çağrılır, asıl işlev (örneğin f1 ) verilen argümanlarla çağrılır. create içinde gerçekleşmiş kurgusal bir örnek olarak (* eşittir) (k1, k2); olabilir.

(*) veya, bu durumda, işlevi create tarafından tahsis edilen yapıdan işaretçilerine getirecek başka bir işlev onları depolar.


Aslında C, ilk önce create (f1, f2, f3); ve ikinci olarak (k1, k2); 'a eşittir; Kolaylık.

2
katma
@DanielMoody İşlev imleçleri C’de gariptir, çünkü her iki yönde de otomatik olarak dönüştürürler. Bunu sana söylemem gerekip gerekmediğini bilmiyorum ama 4. örneğe cs.berkeley.edu/~necula/cil/cil016.html . Her neyse, create (& f1…/(* eşittir) (k1… ve create (f1…/equals (k1… ) arasında rahat edeceğiniz bir stil seçin buna bağlı kalın, ancak bir işlev veya işlev işaretçisi için bir & veya bir * unu unuttuğunuzda derleyici uyarıları almazsanız şaşırmayın.
katma yazar Pascal Cuoq, kaynak
Evet, teşekkür ederim bu çok daha anlamlı. Bu görüntünün sözdizimi öyle garip ki, onunla ne yapacağımı, hatta nasıl bakacağımı bile bilmiyordum.
katma yazar Daniel Moody, kaynak

Bu, parametre olarak işlevler için işaretçiler olarak görünüyor?

Evet. Bu doğru.

Buna nasıl telefon edeceğimi, ne de olsa ne olacağını bile bilmiyorum.

İmzaya uyan işlevleri kullanmanız gerekecek parametrelerin ures ve bu işlevleri kullanarak create arayın. Örnek:

long myHashFunction(void* key) {...}
bool myEqualsFunction(void* key1, void* key2) {...}
void myPrintFunction(void* key1, void* key2)) {...}


Table* table = create(myHashFunction, myEqualsFunction, myPrintFunction);

Bu işlevle create öğesinin yaptığı işlem yalnızca tahmin edilebilir. Onlarla ne yaptığı hakkında hiçbir fikrim yok.

1
katma

Bu, parametre olarak işlevler için işaretçiler olarak görünüyor?

Evet. Bu doğru.

Buna nasıl telefon edeceğimi, ne de olsa ne olacağını bile bilmiyorum.

İmzaya uyan işlevleri kullanmanız gerekecek parametrelerin ures ve bu işlevleri kullanarak create arayın. Örnek:

long myHashFunction(void* key) {...}
bool myEqualsFunction(void* key1, void* key2) {...}
void myPrintFunction(void* key1, void* key2)) {...}


Table* table = create(myHashFunction, myEqualsFunction, myPrintFunction);

Bu işlevle create öğesinin yaptığı işlem yalnızca tahmin edilebilir. Onlarla ne yaptığı hakkında hiçbir fikrim yok.

1
katma

Bu bir yorum olmalı - sığmayacak kadar gabby

Those are function pointers:
          long (*hash)(void* key),  <- returns a long, uses a void * as input
          bool (*equals)(void* key1, void* key2), <- return 0 or 1            (True/False)
          void (*print)(void* key1, void* key2)); <- no return

Bunlar işaretçiler olduğundan, asıl işlev isimleri oluşturduğunuz isimlerdir (veya prof bunları sizin için karma, eşittir ve yazdırmak da dahil olmak üzere herhangi bir isimle oluşturmuş olabilir).

Ancak "karma", bir karma tabloya ofset (belki bir dizi) döndürür. "eşittir", iki girdi değerinin aynı değer olup olmadığını test eder - aynılık tamamen öznel olabilir. Profesyoneline sor. print, sanırım girdiyi bulur ve girdiyi bulur ve karma değer veya bilgileri anahtar değeri için nesnede basar. Ne demek istediğimi görmek için 'ilişkisel dizi' konusuna bakın.

1
katma
Yorumlar normalde cevap olarak gönderilmemelidir, ancak cevap olarak o kadar da kötü değildir, bu yüzden işaretlemediğim ya da reddetmedim.
katma yazar Mooing Duck, kaynak

Bu bir yorum olmalı - sığmayacak kadar gabby

Those are function pointers:
          long (*hash)(void* key),  <- returns a long, uses a void * as input
          bool (*equals)(void* key1, void* key2), <- return 0 or 1            (True/False)
          void (*print)(void* key1, void* key2)); <- no return

Bunlar işaretçiler olduğundan, asıl işlev isimleri oluşturduğunuz isimlerdir (veya prof bunları sizin için karma, eşittir ve yazdırmak da dahil olmak üzere herhangi bir isimle oluşturmuş olabilir).

Ancak "karma", bir karma tabloya ofset (belki bir dizi) döndürür. "eşittir", iki girdi değerinin aynı değer olup olmadığını test eder - aynılık tamamen öznel olabilir. Profesyoneline sor. print, sanırım girdiyi bulur ve girdiyi bulur ve karma değer veya bilgileri anahtar değeri için nesnede basar. Ne demek istediğimi görmek için 'ilişkisel dizi' konusuna bakın.

1
katma
Yorumlar normalde cevap olarak gönderilmemelidir, ancak cevap olarak o kadar da kötü değildir, bu yüzden işaretlemediğim ya da reddetmedim.
katma yazar Mooing Duck, kaynak