Ich bin verwirrt über die Bedeutung von void *function()
.
Ist es ein Zeiger auf eine Funktion oder eine Funktion, die zurückkehrt? void*
? Ich habe es immer für Datenstrukturen als rekursive Funktion verwendet, die einen Zeiger zurückgibt, aber als ich einen Code in Multithreading sah (pthread
) gibt es eine gleiche Funktionsdeklaration. Jetzt bin ich verwirrt, was der Unterschied zwischen ihnen ist.
Ist void *function() ein Zeiger auf eine Funktion oder eine Funktion, die ein void* zurückgibt?
Benutzer9515151
Vlad aus Moskau
Die Funktion hat den Rückgabetyp void *
.
void *function();
Daher ziehe ich es in solchen Fällen immer vor, das Symbol zu trennen *
aus dem Funktionsnamen wie
void * function();
Und wie Jarod42
auf die in einem Kommentar verwiesen wird, können Sie die Funktionsdeklaration in C++ umschreiben, indem Sie den nachgestellten Rückgabetyp like verwenden
auto function() -> void *;
Wenn Sie einen Zeiger für eine Funktion deklarieren möchten, sollten Sie schreiben
void ( *function )();
wo der Rückgabetyp ist void
Oder
void * ( *function )();
wo der Rückgabetyp void *
.
Oder ein Zeiger auf eine Funktion, der einen Zeiger auf eine Funktion zurückgibt
void * ( *( *function )() )();
-
Deshalb schreibe ich lieber
void* function();
. Das ist nicht so verlockend… 😉 (Die Bearbeitung geschah gerade während ich dies schrieb.)– Scheffs Katze
22. Oktober 2019 um 9:14 Uhr
-
im Code erkläre ich
void * reader();
dann weiterpthread_create(&thread1,null,reader,reader_arg)
Anstatt vonpthread_create(&thread1,null,&reader,reader_arg)
– Benutzer9515151
22. Oktober 2019 um 9:19 Uhr
-
@Scheff: Oder sogar
auto function() -> void*
(C++). 🙂– Jarod42
22. Oktober 2019 um 9:26 Uhr
-
Oder ein Zeiger auf eine Funktion, der einen Zeiger auf eine Funktion zurückgibt Das ist, was
typedef
ist für… 😉– Andreas Henle
22. Oktober 2019 um 9:41 Uhr
-
@AndrewHenle Mit typedef gibt es uns kein Problem. Ein Problem tritt auf, wenn Deklarationen ohne typedef oder eine Alias-Deklaration verwendet werden.:)
– Vlad aus Moskau
22. Oktober 2019 um 9:42 Uhr
Immer wenn ich mir bei C-Syntaxproblemen nicht sicher bin, verwende ich gerne die cdekl Dienstprogramm (online Version) für mich interpretieren. Es übersetzt zwischen C-Syntax und Englisch.
Zum Beispiel gebe ich Ihr Beispiel von ein void *foo()
und es kam zurück
Deklarieren Sie foo als Funktion, die den Zeiger auf void zurückgibt
Um zu sehen, wie die andere Syntax aussehen würde, gebe ich ein declare foo as pointer to function returning void
und es kam zurück
nichtig (*foo)()
Dies ist besonders nützlich, wenn Sie mehrere Ebenen von Typumwandlungen, Sternen oder Klammern in einem einzigen Ausdruck haben.
Es ist eine Funktion, die einen Zeiger auf zurückgibt void
.
Stellen Sie sich Ihre Erklärung so vor:
void *(function());
Dies wäre eine Funktion, die zurückkehrt void
(oder nichts):
void (*function2)();
Stellen Sie sich die obige Deklaration folgendermaßen vor:
void ((*function2)());
Eine viel einfachere Art, diese zu schreiben, ist die Verwendung typedef
s:
typedef void *function_returning_void_pointer();
typedef void function_returning_nothing();
function_returning_void_pointer function;
function_returning_nothing *function2;
Dies beseitigt im Allgemeinen die Verwirrung um Funktionszeiger und ist viel einfacher zu lesen.
Deklarationen in C/C++ werden vom Bezeichner nach außen gelesen folgenden Operatorvorrang.
Ein kurzer Blick auf die C/C++-Operatorvorrangtabelle in Wikipedia zeigt, dass der Funktionsaufrufoperator ()
hat eine höhere Priorität als der Indirektionsoperator *
. Ihre Funktionsdeklarationen lauten also so:
-
Beginnen Sie bei der Kennung:
function
ist -
function()
eine Funktion, die keine Argumente akzeptiert -
void* function()
und gibt a zurückvoid*
.
Dieses allgemeine Prinzip gilt auch für Array-Deklarationen ([]
hat auch eine höhere Priorität als *
) und Kombinationen aus beidem. So
int *(*arr[42])();
wird gelesen als
arr
istarr[42]
ein Array von 42 Elementen, die sind*arr[42]
Hinweise auf(*arr[42])()
Funktionen, die keine Argumente annehmen undint *(*arr[42])()
Rückkehr einint*
.
Es ist etwas gewöhnungsbedürftig, aber sobald Sie das Prinzip verstanden haben, ist es einfach, diese Deklarationen eindeutig zu lesen.
@goodvibration C wurde formatfrei gemacht (und C++ hat dies “geerbt”). Eben
void*function();
ist syntaktisch korrekt. ZB für Python haben sie eine andere Entscheidung getroffen – das Format ist Teil der Syntax. IMHO, beide Wege haben ihre Vor- und Nachteile.– Scheffs Katze
22. Oktober 2019 um 9:17 Uhr
@goodvibration Je mehr Sie versuchen, den Programmierer davor zu schützen, das zu tun, was er will, desto mehr bekommen Sie so etwas wie Java;)
– 463035818_ist_keine_Nummer
22. Oktober 2019 um 9:20 Uhr
@goodvibration Weniger Optionen, weniger Flexibilität. Und denken Sie bitte daran, dass es Jahrzehnte her ist, als sie es taten. Es ist leicht, sich hinterher zu beschweren… 😉
– Scheffs Katze
22. Oktober 2019 um 9:20 Uhr
In der C-Sprache
void *function()
ist eine Funktion, die eine beliebige Anzahl von Argumenten akzeptiert und einen Wert zurückgibt, der, wenn er dereferenziert wird, vom Typ ist Leere. In C++,void* function()
ist eine Funktion, die keine Argumente akzeptiert und einen Wert von zurückgibt Zeiger auf Leere. Sie sollten sich entscheiden, nach welcher Sprache Sie fragen.– Stephen M. Webb
22. Oktober 2019 um 18:42 Uhr
@StephenM.Webb Sie können a nicht dereferenzieren
void *
. Denn selbst wenn du könntest, was würdest du mit a machenvoid
?– Fabio sagt, Monica wieder einzusetzen
22. Oktober 2019 um 22:48 Uhr