Was ist der Unterschied zwischen float * varname und float * varname im klassischen C?
Formatierung. Das ist es. Sie meinen das Gleiche.
Wo du den Raum platzierst (oder wenn du überhaupt einen hast), ist eine Frage der Präferenz. Einige bevorzugen das * neben dem Variablennamen, damit Sie nicht durch etwas wie:
verwirrt werden %Vor%(hier ist nur a ein Zeiger, b ist nicht)
Andere argumentieren, dass sie niemals mehrere Variablen auf einmal deklarieren, daher bevorzugen sie das * neben float, da es Teil des Typs ist.
Es gibt keinen Unterschied. Das Leerzeichen wird komplett ignoriert.
Beachten Sie jedoch, dass Folgendes irreführend sein kann:
%Vor%Wenn Sie das oben Genannte untersuchen, werden Sie denken, dass sowohl var1 als auch var2 Zeiger auf einen Float sind. Allerdings liegst du falsch, denn das deklariert var1 als Zeiger auf einen Gleitkommawert, aber var2 wäre ein regulärer Gleitkommawert.
Letzteres ist expliziter, da es zeigt, dass Sie eine Variable erstellen, die ein Zeiger auf ein Float ist, anstatt eine Variable zu erstellen, die ein Float-Zeiger ist. Dies wird wichtig in Konstrukten wie:
%Vor%foo ist ein Zeiger auf ein float, aber bar ist nur ein float.
Meistens ist es eine Frage des Programmierstils. Die meisten C-Programmierer ziehen es jedoch vor, die zweite Option zu verwenden: float *var;
, da sie näher an die Syntax der Sprache gebunden ist.% Co_de% asterisk: Die *
ist an den Deklarator gebunden, nicht an den Spezifizierer vom Typ.
Mit anderen Worten übersetzen C-Programmierer *
, da float *var
vom Typ float ist. aber nicht *var
ist vom Typ var
.
Es gibt ausführlichere Erklärungen im Wikipedia-Artikel C-Variablentypen und -deklarationen
Sie können auch die Frage C Pointer Syntax: Style-Umfrage interessant finden.
Wie andere gesagt haben, macht das keinen Unterschied - Stilsache. Beachten Sie, dass in C ++ üblicherweise geschrieben wird:
%Vor%Weil der Zeiger Teil des Typs ist - zumindest gilt dies für benutzerdefinierte Typen. Aber auch für eingebaute Typen. Es macht also in C einen Sinn, dasselbe zu tun, um konsistent zu sein. Persönlich finde ich es intuitiver, einen Zeigerteil des Typs zu haben.
Es gibt praktisch keinen Unterschied; Die Deklaration wird analysiert als ob sie geschrieben wäre float (*varname);
.
Sowohl in C als auch in C ++ sind Deklarationen um Ausdrücke zentriert, nicht Objekte; Grundsätzlich sollte die Form der Deklaration mit der Form des Ausdrucks in ausführbarem Code übereinstimmen (IOW, Verwendung der Deklaration). Wenn Sie z. B. einen Zeiger auf eine Ganzzahl mit dem Namen p
haben und auf diesen Integer -Wert zugreifen möchten, auf den p
zeigt, wird der Zeiger wie folgt dereferenziert:
Der Typ des Ausdrucks *p
ist int; Daher sollte die Deklaration wie
Wenn Sie ein Array mit dem Namen arr
haben und auf den ganzzahligen Wert eines bestimmten Elements i
zugreifen möchten, würden Sie
Der Typ des Ausdrucks a[i]
ist int; Daher sollte die Deklaration wie
In den obigen Beispielen heißen *p
und a[N]
deklaratoren ; Deklaratoren führen den Namen des deklarierten Objekts zusammen mit zusätzlichen Typinformationen ein, die nicht im Typspezifizierer enthalten sind. Die Ganzzahl von p
und a
wird durch den Typbezeichner int
bereitgestellt, aber die Pointer-Ness von p
und die Array-Ness von a
werden von ihren jeweiligen Deklaratoren zur Verfügung gestellt
Dies ist ein wichtiger Punkt und etwas, das betont werden muss; Die *
von int *p;
und int* p;
ist unabhängig vom Leerzeichen an den Deklarator und nicht an den Typspezifizierer gebunden. Die Tatsache, dass Sie es so oder so schreiben können, ist ein Zufall der C- (und C ++ -) Syntax, und infolgedessen gibt es eine Denkrichtung, dass Zeigervariablen als T* p;
deklariert werden sollten, im Gegensatz zu T *p;
, da die type von p
ist "Zeiger auf T". Mein Problem ist, dass Argument only nur für einfache Zeigertypen funktioniert; Array- oder Funktionstypen können nicht auf die gleiche Weise behandelt werden. Zum Beispiel können wir int[N] arr;
nicht schreiben, obwohl der -Typ von arr
"N-Element-Array von int" ist. Es fällt wirklich, wenn wir Zeiger auf Arrays oder Zeiger auf Funktionen oder Kombinationen von solchen deklarieren. Zum Beispiel:
Der -Typ von farr
ist "Zeiger auf eine Funktion, die einen Zeiger auf ein N-Element-Array von Zeigern auf Funktionen zurückgibt, die Zeiger auf int zurückgeben". Alles andere als "int" ist Teil des Deklarators; write int* (*(*(*farr)())[N])();
oder sogar int*(*(*(* farr)())[N])();
wäre einfach ... albern.
Ich glaube, dass das Beibehalten von T* p;
für Zeigerdeklarationen zu mehr Verwirrung führt, nicht weniger. Ähnlich wie Stroustrup und Legionen von C ++ - Programmierern gerne etwas anderes vorgeben würden, sind Deklarationen in C und C ++ um Ausdrücke zentriert, nicht um Objekte.
Da ich Teil eines größeren Teams bin, das C ++ - Code schreibt, befolge ich die vereinbarten Kodierungsrichtlinien, die Zeiger und Referenzen als T* p;
und T& r;
deklarieren, aber es bringt mich jedes Mal dazu meine Zähne zu knirschen es zu tun.