Ist void * function () ein Zeiger auf function oder eine Funktion, die void * zurückgibt?


26

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 ( pthread) sah, gab es dieselbe Funktionsdeklaration. Jetzt bin ich verwirrt, was der Unterschied zwischen ihnen ist.


5
@goodvibration C wurde formatfrei gemacht (und C ++ "erbte" dies). Auch void*function();ist syntaktisch korrekt. Zum Beispiel haben sie für Python ein anderes Entscheidungsformat gewählt - das Format ist Teil der Syntax. IMHO haben beide Wege ihre Vor- und Nachteile.
Scheff

3
@goodvibration je mehr Sie versuchen, den Programmierer vor dem zu schützen, was er will, desto mehr erhalten Sie so etwas wie Java;)
idclev 463035818

2
@goodvibration Weniger Optionen, weniger Flexibilität. Und bitte denken Sie daran, dass es Jahrzehnte her ist, als sie es getan haben. Es ist leicht, sich danach zu beschweren ... ;-)
Scheff

2
In der C-Sprache void *function()ist dies eine Funktion, die eine beliebige Anzahl von Argumenten verwendet und einen Wert zurückgibt, der bei Dereferenzierung vom Typ void ist . In C ++ void* function()ist eine Funktion, die keine Argumente akzeptiert und den Wert pointer-to-void zurückgibt . Sie sollten sich entscheiden, nach welcher Sprache Sie fragen.
Stephen M. Webb

1
@ StephenM.Webb Du kannst nicht dereferenzieren avoid * . Selbst wenn Sie könnten, was würden Sie mit einem machen void?
Fabio sagt Reinstate Monica

Antworten:


38

Die Funktion hat den Rückgabetyp void *.

void *function();

Deshalb ziehe ich es in solchen Fällen immer vor, das Symbol *vom Funktionsnamen wie zu trennen

void * function();

Und wie Jarod42in einem Kommentar erwähnt, können Sie die Funktionsdeklaration in C ++ mit dem nachfolgenden Rückgabetyp wie neu schreiben

auto function() -> void *;

Wenn Sie einen Zeiger auf Funktion deklarieren möchten, sollten Sie schreiben

void ( *function )();

Oder

void * ( *function )();

Oder ein Zeiger auf eine Funktion, der einen Zeiger auf eine Funktion zurückgibt

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

2
Deshalb schreibe ich lieber void* function();. Das ist nicht so verlockend ... ;-) (Die Bearbeitung geschah gerade während des Schreibens.)
Scheff

im Code erkläre ich void * reader();dann auf pthread_create(&thread1,null,reader,reader_arg)anstelle vonpthread_create(&thread1,null,&reader,reader_arg)
user9515151

1
@Scheff: Oder sogar auto function() -> void*(C ++). :)
Jarod42

3
Oder ein Zeiger auf Funktion , dass kehrt zum Funktionszeiger das ist , was typedeffür ist ... ;-)
Andrew Henle

1
@ 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

7

Wenn ich mir bei Problemen mit der C-Syntax nicht sicher bin, verwende ich gerne das Dienstprogramm cdecl ( Online-Version ), um es für mich zu interpretieren. Es übersetzt zwischen C-Syntax und Englisch.

Zum Beispiel habe ich Ihr Beispiel eingegeben void *foo()und es ist zurückgekehrt

deklarieren Sie foo als Funktion, die den Zeiger auf void zurückgibt

Um zu sehen, wie die andere Syntax aussehen würde, habe ich eingegeben declare foo as pointer to function returning voidund sie zurückgegeben

void (* foo) ()

Dies ist besonders nützlich, wenn Sie mehrere Ebenen von Typografien, Sternen oder Klammern in einem einzigen Ausdruck haben.


2

Es ist eine Funktion, die einen Zeiger auf zurückgibt void.

Stellen Sie sich Ihre Erklärung folgendermaßen vor:

void *(function());

Dies wäre eine Funktion, die zurückgibt void(oder nichts):

void (*function2)();

Stellen Sie sich die obige Erklärung folgendermaßen vor:

void ((*function2)());

Eine viel einfachere Möglichkeit, diese zu schreiben, ist die Verwendung von typedefs:

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.


0

Deklarationen in C / C ++ werden nach der Priorität des Operators vom Bezeichner nach außen gelesen .

Ein kurzer Blick auf die Prioritätstabelle des C / C ++ - Operators in Wikipedia zeigt, dass der Funktionsaufrufoperator ()eine höhere Priorität hat als der Indirektionsoperator *. Ihre Funktionsdeklarationen lauten also wie folgt:

  • Beginnen Sie mit der Kennung: functionis

  • function() Eine Funktion, die keine Argumente akzeptiert

  • void* function()und gibt a zurück void*.

Dieses allgemeine Prinzip gilt auch für Array-Deklarationen (hat []ebenfalls eine höhere Priorität als *) und Kombinationen der beiden. Damit

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

wird gelesen als

  • arr ist
  • arr[42] ein Array von 42 Elementen, die sind
  • *arr[42] Zeiger auf
  • (*arr[42])() Funktionen, die keine Argumente annehmen und
  • int *(*arr[42])()Rückgabe eines int*.

Es dauert ein bisschen, bis man sich daran gewöhnt hat, aber wenn man das Prinzip verstanden hat, ist es einfach, diese Erklärungen eindeutig zu lesen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.