Void * function () è un puntatore a funzione o una funzione che restituisce un vuoto *?


26

Sono confuso sul significato di void *function().
È un puntatore a funzione o una funzione che ritorna void*? L'ho sempre usato su strutture di dati come una funzione ricorsiva che restituisce un puntatore, ma quando ho visto un codice in multithreading ( pthread) c'è una stessa dichiarazione di funzione. Ora sono confuso qual è la differenza tra loro.


5
@goodvibration C è stato reso privo di formato (e C ++ lo ha "ereditato"). Anche void*function();sintatticamente è corretto. Ad esempio per Python hanno scelto una decisione diversa: il formato fa parte della sintassi. IMHO, entrambi i modi hanno i suoi pro e contro.
Scheff,

3
@goodvibration più provi a proteggere il programmatore dal fare quello che vogliono più ottieni qualcosa come java;)
idclev 463035818

2
@goodvibration Meno opzioni, meno flessibilità. E, per favore, tieni presente che sono passati decenni da quando lo hanno fatto. È facile lamentarsi in seguito ... ;-)
Scheff

2
Nel linguaggio C, void *function()è una funzione che accetta un numero arbitrario di argomenti e restituisce un valore che, se non definito, è di tipo nullo . In C ++, void* function()è una funzione che non accetta argomenti e restituisce un valore di pointer-to-void . Dovresti decidere quale lingua stai chiedendo.
Stephen M. Webb,

1
@ StephenM.Webb Non puoi dereference avoid * . Dopo tutto, anche se tu potessi, cosa faresti con un void?
Fabio dice di reintegrare Monica il

Risposte:


38

La funzione ha il tipo restituito void *.

void *function();

Quindi preferisco sempre in questi casi separare il simbolo *dal nome della funzione come

void * function();

E come Jarod42indicato in un commento, puoi riscrivere la dichiarazione di funzione in C ++ usando il tipo di ritorno finale come

auto function() -> void *;

Se si desidera dichiarare un puntatore a funzionare, è necessario scrivere

void ( *function )();

O

void * ( *function )();

O un puntatore alla funzione che restituisce il puntatore alla funzione

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

2
Ecco perché, preferisco scrivere void* function();. Non è così allettante ... ;-) (La modifica è avvenuta proprio mentre scrivevo questo.)
Scheff

nel codice dichiaro void * reader();quindi al pthread_create(&thread1,null,reader,reader_arg)posto dipthread_create(&thread1,null,&reader,reader_arg)
user9515151

1
@Scheff: O anche auto function() -> void*(C ++). :)
Jarod42,

3
O un puntatore alla funzione che restituisce il puntatore alla funzione Ecco a cosa typedefserve ... ;-)
Andrew Henle

1
@AndrewHenle Con typedef non ci sono problemi. Un problema sorge quando le dichiarazioni vengono utilizzate senza typedef o una dichiarazione alias. :)
Vlad da Mosca,

7

Ogni volta che non sono sicuro dei problemi di sintassi C, mi piace usare l' utilità cdecl ( versione online ) per interpretare per me. Si traduce tra sintassi C e inglese.

Ad esempio, ho inserito il tuo esempio di void *foo()ed è tornato

dichiarare foo come funzione restituendo il puntatore a vuoto

Per vedere come sarebbe stata l'altra sintassi, ho inserito declare foo as pointer to function returning voide restituito

void (* foo) ()

Ciò diventa particolarmente utile quando hai più livelli di dattiloscritti, stelle o parentesi in una singola espressione.


2

È una funzione che restituisce un puntatore a void.

Pensa alla tua dichiarazione in questo modo:

void *(function());

Questa sarebbe una funzione che ritorna void(o niente):

void (*function2)();

Pensa alla dichiarazione sopra in questo modo:

void ((*function2)());

Un modo molto più semplice per scrivere questi è usare typedefs:

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

function_returning_void_pointer function;
function_returning_nothing *function2;

Questo generalmente elimina la confusione attorno ai puntatori di funzione ed è molto più facile da leggere.


0

Le dichiarazioni in C / C ++ vengono lette dall'identificatore verso l' esterno dopo la precedenza dell'operatore .

Una rapida occhiata alla tabella di precedenza degli operatori C / C ++ in Wikipedia rivela che l'operatore di chiamata di funzione ()ha una precedenza più alta dell'operatore di riferimento indiretto *. Quindi, le dichiarazioni delle funzioni sono così:

  • Inizia dall'identificatore: functionè

  • function() una funzione che non accetta argomenti

  • void* function()e restituisce a void*.

Questo principio generale vale anche per le dichiarazioni di array ( []ha anche una precedenza più alta di *) e le combinazioni dei due. Così

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

viene letto come

  • arr è
  • arr[42] una matrice di 42 elementi che sono
  • *arr[42] puntatori a
  • (*arr[42])() funzioni che non accettano argomenti e
  • int *(*arr[42])()restituire un int*.

Ci vuole un po 'per abituarsi a questo, ma una volta compreso il principio, è facile leggere queste dichiarazioni senza ambiguità.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.