Void * function () işlev için bir işaretçi mi yoksa void * döndüren bir işlev mi?


26

Anlamı hakkında kafam karıştı void *function().
Bir işaretçi void*mi, yoksa dönen bir fonksiyon mu? Ben her zaman bir işaretçi dönen özyinelemeli bir işlev olarak veri yapıları üzerinde kullandım, ama ben multithreading ( pthread) bir kod gördüğümde aynı işlev bildirimi vardır. Şimdi aralarındaki farkın ne olduğunu karıştırıyorum.


5
@ goodvibration C formatsız hale getirildi (ve C ++ bunu miras aldı). Hatta void*function();sözdizimsel olarak doğrudur. Python için farklı bir karar biçimi seçtiler - sözdiziminin bir parçası. IMHO, her iki şekilde de yanlısı ve aleyhte.
Scheff

3
@ goodvibration daha fazla programcıyı istediklerini yapmaya karşı korumaya çalıştığınızda java gibi bir şey elde edersiniz;)
idclev 463035818

2
@goodvibration Daha az seçenek, daha az esneklik. Ve lütfen, onlarca yıl önce bunu yaptıklarını unutmayın. Daha sonra şikayet etmek kolaydır ... ;-)
Scheff

2
C dilinde, void *function()isteğe bağlı sayıda argüman alan ve kayıttan çıkarıldığında geçersiz olan bir değer döndüren bir işlevdir . C ++ ' void* function()da argüman almayan ve pointer-void değerini döndüren bir fonksiyondur . Hangi dilde sorulduğuna karar vermelisin.
Stephen M. Webb

1
@ StephenM.Webb Atıftan vazgeçilemez avoid * . Sonuçta, yapabilseniz bile, a ile ne yapardınız void?
Fabio, Reinstate Monica'ya

Yanıtlar:


38

İşlev dönüş tipine sahiptir void *.

void *function();

Bu yüzden her zaman sembolü *böyle fonksiyon isminden ayırmayı tercih ederim

void * function();

Jarod42Bir yorumda belirtildiği gibi , C ++ 'daki fonksiyon bildirimini aşağıdaki gibi geri dönüş türünü kullanarak yeniden yazabilirsiniz.

auto function() -> void *;

Bir işaretçi işlevini bildirmek istiyorsanız,

void ( *function )();

Veya

void * ( *function )();

Veya işaretçiyi işlevine döndüren bir işaretçi işlev

void * ( *( *function )() )();

2
Bu yüzden yazmayı tercih ederim void* function();. O kadar cazip değil ... ;-) (Düzenleme sadece bunu yazarken oldu.)
Scheff

kodunda ı beyan void * reader();üzerine daha sonra pthread_create(&thread1,null,reader,reader_arg)yerinepthread_create(&thread1,null,&reader,reader_arg)
user9515151

1
@Scheff: Ya ​​da auto function() -> void*(C ++). :)
Jarod42

3
Veya işlev için işaretçiyi döndüren bir işaretçi İşte bu ne typedefiçindir ... ;-)
Andrew Henle

1
@AndrewHenle typedef ile sorun yok. Bildirimler typedef veya takma ad bildirimi olmadan kullanıldığında bir sorun ortaya çıkar. :)
Moskova'dan Vlad,

7

C sözdizimi sorunları hakkında emin olmadığımda, benim için yorumlamak için cdecl yardımcı programını ( çevrimiçi sürüm ) kullanmayı seviyorum . C sözdizimi ve İngilizce arasında çeviri yapar.

Örneğin, örneğinizi girdim void *foo()ve geri döndü

foo'yu işaretçi boşluğa döndüren işlev olarak bildir

Diğer sözdiziminin nasıl görüneceğini görmek için girdim declare foo as pointer to function returning voidve geri döndü

geçersiz (* foo) ()

Bu, özellikle tek bir ifadede birden fazla daktilo, yıldız veya parantez seviyeniz olduğunda yararlı olur.


2

İşaretçiyi döndüren bir işlevdir void.

Beyanınızı şu şekilde düşünün:

void *(function());

Bu dönen bir işlev olacaktır void(ya da hiçbir şey):

void (*function2)();

Yukarıdaki beyanı şu şekilde düşünün:

void ((*function2)());

Bunları yazmanın çok daha kolay bir yolu typedefs kullanmaktır :

typedef void *function_returning_void_pointer();
typedef void function_returning_nothing();

function_returning_void_pointer function;
function_returning_nothing *function2;

Bu genellikle işlev işaretçileri etrafındaki karışıklığı ortadan kaldırır ve okunması çok daha kolaydır.


0

C / C ++ 'da yapılan bildirimler, işleç önceliğinin ardından tanımlayıcıdan dışarı doğru okunur .

Vikipedi'deki C / C ++ operatör öncelik tablosuna hızlı bir bakış , işlev çağrısı operatörünün ()dolaylı operatörden daha yüksek bir önceliğe sahip olduğunu gösterir *. Yani, işlev bildirimleriniz şöyle:

  • Tanımlayıcı başlayın: functionolduğunu

  • function() argüman almayan bir işlev

  • void* function()ve a değerini döndürür void*.

Bu genel ilke aynı zamanda dizi bildirimleri ( []daha yüksek önceliğe sahiptir *) ve bu ikisinin kombinasyonları ile de geçerlidir. Yani

int *(*arr[42])();

olarak okundu

  • arr dır-dir
  • arr[42] 42 elemanlık bir dizi
  • *arr[42] işaretçiler
  • (*arr[42])() argüman almayan fonksiyonlar ve
  • int *(*arr[42])()dönüş int*.

Buna alışmak biraz zaman alır, ancak prensibi anladıktan sonra, bu beyanları açık bir şekilde okumak kolaydır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.