int * i; oder int * i; oder int * i; [geschlossen]

30

Was ist Ihre Lieblingsmethode, um einen Zeiger zu deklarieren?

int* i;

oder

int *i;

oder

int * i;

oder

int*i;

Bitte erklären Sie warum.

Siehe auch: http://www.stroustrup.com/bs_faq2.html#whitespace

lesmana
quelle
19
Ich würde mich lieber auf die anderen 3000 Zeilen konzentrieren ...
29
int*i;- Weißraum wächst nicht auf Bäumen, wissen Sie ...
Shog9
Dies ist im Wesentlichen die gleiche Frage; Hier ist meine Antwort .
Keith Thompson

Antworten:

75

Wenn du schreibst:

int* i, j, k;

Sie schlagen irreführend vor, dass alle i, j und k Zeiger auf sind int.

Ich behaupte, es ist besser, das * an den Variablennamen anzuhängen.

Randall Schulz
quelle
35
Und ich würde vorschlagen, int * i;dass es sich nur deshalb nicht um einen Konkurrenten handelt, weil es auf einen Blick wie eine Multiplikation aussieht.
John K
1
+1, weil ich dieses Szenario vorher nicht in Betracht gezogen habe.
Pops
4
"Sie schlagen irreführend vor, dass alle i, j und k Zeiger auf int sind." Es sei denn, Sie schreiben C #, wobei C # int*als Typ betrachtet wird und int* i, jzwei Zeiger deklariert. Die Frage könnte als unvollständig angesehen werden - es hängt von der verwendeten Sprache ab, welche Stile angemessen sind. In CI folge int *xich, in C # mache ich es anders.
Joren
1
@Joren: Entschuldigung, ich bin kein C # -Programmierer. Ich habe einfach angenommen, dass das Codefragment in der Frage C oder C ++ ist.
Randall Schulz
Ich denke, es ist völlig vernünftig anzunehmen, dass es sich um C oder C ++ handelt, es sei denn, C # wird ausdrücklich erwähnt. In C # sieht man sehr oft keine Zeiger.
Alternative
62

Ich bevorzuge, int* iweil ies den Typ "Zeiger auf ein int" hat, und ich glaube, dies macht es mit dem Typsystem einheitlich. Natürlich tritt das bekannte Verhalten ein, wenn versucht wird, mehrere Zeiger auf einer Zeile zu definieren (das Sternchen muss vor jedem Variablennamen stehen, um einen Zeiger zu deklarieren), aber ich deklariere Zeiger einfach nicht auf diese Weise. Ich denke auch, dass es ein schwerwiegender Fehler in C-Sprachen ist.

Tamás Szelei
quelle
8
Auch ich folge dieser Konvention. Aus dem gleichen Grunde.
Gablin
5
Persönlich, wenn ich mehrere Zeiger in meinem Code deklariere, behandle ich es als Code-Geruch. Ich sollte nicht so viele Hinweise brauchen; und normalerweise nicht. Das Problem der Mehrfachdeklaration in einer einzelnen Zeile taucht in keinem Code auf, den ich schreibe: Eine Deklaration pro Zeile.
greyfade
5
Das Problem dabei ist, dass der Typ kein "Zeiger auf ein int" ist. C (und C ++) haben keinen Zeigertyp. Es ist ein Zeiger auf einen Speicherblock vom Typ int.
Billy ONeal
10
Ich würde behaupten, das *ihat eine Art von int.
Tim Goodman
5
@Billy: Wenn ja, ich habe diese Verwirrung in 12 Jahren des Versuchs, Standardesisch zu verstehen, zu analysieren und zu erklären, noch nie gesehen. "Pointer to an int" ist ein vollkommen gültiger Typ in C und C ++.
23

Für C, wo wir keinen starken Fokus auf Typen haben, bevorzuge ich:

int *i;

Weil es eine Betonung auf dem hat int, nicht auf dem Zeiger. Was ist das int? *iist die int.

Alternative
quelle
2
Guter Punkt. Mit Zeigern können Sie sich den Start als Teil des Namens vorstellen. Wenn Sie beispielsweise int i = 5den Wert von haben i, verwenden Sie den Namen i. Ebenso verwenden Sie, wenn Sie haben int *i; *i = 5, um den Wert zu erhalten *i.
Mipadi
Ich lese int * i als: * i ist ein int. Daher ist i ein Zeiger auf int. Variablendeklarationen in C verwenden Typausdrücke, int und * sind nur Operatoren. int * i analysiert als int (* (i)) und wird so interpretiert, als ob i einen Zeiger auf eine Ganzzahl hat. char * p [] parst als char (* ([] (p))) (weil [] Vorrang vor * hat) und bedeutet: p hat den Typ array-of pointer-to char.
Giorgio
Aus diesem Grund, glaube ich, haben sie * neben die Variable geschrieben, weil * ein Operator ist, der auf sie angewendet wird.
Giorgio
7

Ich habe int* ijahrelang bevorzugt . Es gibt jedoch ein starkes Argument dafür, int *idass Sie sich bei Verwendung des früheren Stils immer noch an die Mehrfachdeklarationsregel erinnern müssen:

int* a, *b; // not int* a, b;

Weil Sie sich an diese Regel erinnern müssen, gewinnen Sie nicht einfach - aber ich würde auch nicht sagen, dass sie komplexer ist. Das Vermeiden mehrerer Deklarationen in einer Zeile ist nur eine andere Möglichkeit, um zu sagen, dass Sie sich an diese Regel erinnern. Der Unterschied zwischen den beiden Stilen ist umstritten.

Selbst wenn ich es verwende, fühlt es sich ein bisschen albern an, so zu tun, als würde die C-Deklarationssyntax anders funktionieren, als dies der Fall ist, indem das Sternchen neben dem Typ und nicht neben der Variablen platziert wird, an die es syntaktisch gebunden ist.

Ich kaufe nicht in , dass man betont den Zeigertyp (z i) , während die andere den int - Typen (für betont *i), aber das kann sein , dass nach 15 Jahren von C und C ++ verwendet, ist es einfach ist , wenn ich es sehe, ohne darüber nachdenken müssen - etwas, was die meisten Anfänger, die diese Frage stellen, noch nicht können.

Auch wenn ich es vorziehen würde, finde ich es nicht unangenehm, Code in einem anderen Stil zu lesen / schreiben. Beständigkeit, bla bla bla.

Keine Notwendigkeit zu erwähnen int * i.


quelle
6

Ich bevorzuge den ersten. Es ist natürlich, ein Zeiger zu sein, das gehört zum Typ.

Da ich C # verwende, werden Typen intuitiver behandelt als in C, sodass es kein Problem gibt, mehrere Zeiger in derselben Anweisung zu deklarieren:

int* a, b, c; // three pointers
Guffa
quelle
4

Wenn Sie mehrere Variablen deklarieren möchten, aber das Sternchen nicht wiederholen möchten:

template <typename T>
struct pointer_to
{
    typedef T* type;
};

pointer_to<int>::type p1, p2, p3;

(Wie Sie in der Strukturvorlage sehen können, bevorzuge ich den int* iStil.)

Und hier ist eine allgemeinere Lösung:

template <typename T>
struct identity
{
    typedef T type;
};

identity<int*>::type p1, p2, p3;

Dieser funktioniert mit jedem "problematischen Typ", zum Beispiel Arrays und Referenzen:

identity<int[10]>::type a1, a2, a3;

identity<int&>::type r1(*p1), r2(*p2), r3(*p3);
fredoverflow
quelle
omg, c ++ zeigt mir immer etwas neues :). Vielen Dank!
Tamás Szelei
1
OMG, C ++ ist schrecklich! typedef int* int_ptrhätte den Trick getan. Klar, ich muss ein neues typedef für verschiedene Zeigertypen deklarieren, aber wie viele werden das in der Praxis sein? Höchstens acht?
Benzado
1
@benzado In der Praxis brauchen Sie weder das typedef noch einen der vorgestellten Tricks, da keine vernünftige Person mehrere Variablen in einer Zeile deklariert. Trotzdem interessant.
Fredoverflow
2
Ich weiß, ich habe eher mit der Tendenz von C ++ - Programmen gesprochen, Sprachfunktionen zu verwenden, nur weil sie es können.
Benzado
@benzado: !!! Ich habe das so oft gesehen!
Giorgio
2

Ich würde gehen, int* i;da der erste Teil den Variablentyp (Zeiger auf int) bezeichnet, während der zweite Teil den Namen ( i) bezeichnet. Es würde für mich keinen Sinn ergeben, dass der Typ intund der Name sind *i. Außerdem int * i;sieht ein bisschen wie Multiplikation zu mir.

Allon Guralnek
quelle
Die Syntax der C-Deklaration ist in dieser Hinsicht nicht konsistent, da die Typinformationen leicht hinter dem Bezeichner stehen können: Arrays sind das klarste Beispiel.
@ Roger: Ich weiß, aber diese Frage betraf speziell eine einzelne Variablendeklaration und sonst nichts.
Allon Guralnek
Ich denke, das liest ein bisschen viel hinein. :) So wie ich die Frage verstehe, fragt es mich, welchen Stil du überall verwendest.
@ Roger: Sie haben wahrscheinlich Recht, aber mein Ziel war es, die Frage des OP zu beantworten: "Was ist Ihre Lieblingsmethode, um einen Zeiger zu deklarieren?". Offensichtlich steht es jedem frei, sich mit dem in der Frage behandelten Thema auseinanderzusetzen, und es wird hier sogar empfohlen. Als jemand, der sich nicht in C / C ++ entwickelt, hatte ich das Gefühl, dass dies zu weit von meinem Fachgebiet entfernt ist.
Allon Guralnek
2

In Erklärungen, die ich verwende int * i;, liest du es als i is a pointer to an integer.

Der Zeiger trägt sowohl zum Typ als auch zur Variablen bei, sodass er sich in der Mitte befinden sollte.

Es ist eine gute Sache zu vermeiden, mehrere Dinge in derselben Zeile zu deklarieren: int * i, j;

Tamara Wijsman
quelle
1

Ich verwende eigentlich alle drei Konventionen unter bestimmten Umständen. Auf den ersten Blick scheine ich inkonsistent, aber ...

  • int * Wenn der Bezeichner nicht vorhanden ist, um visuell zu verdeutlichen, dass der Name nicht vorhanden ist.
  • int* intptron typedefs und ähnliche Erklärungen, um visuell zu verdeutlichen, dass es sich um einen Teil des Typs handelt. Ähnlich bei Funktionszeigerdeklarationen:(int* (*foo)(int))
  • int *identifierund class &identifierauf Funktionsparametern, um visuell zu verdeutlichen, dass der Parameter möglicherweise ein sogenannter "out" -Parameter ist.
  • const int * const * constwann immer ich cv qualifier benutze .
  • int * foo; auf lokalen Erklärungen.

Ich denke, ich bin etwas visuell orientiert.

greyfade
quelle
1

In C gibt es keine Zeigertypen! "Int *" bedeutet also nichts. Das Sternchen ist immer an das rechts davon geschriebene Element gebunden, es gehört zu dem rechts davon stehenden Element. "* i" ist ein Int. Und weil * i ein int ist, folgt daraus, dass i ein Zeiger auf int ist. Das ist die Logik dahinter und deshalb ist "int * i" die einzig mögliche Lösung. Alles andere ist eine Illusion (die in den meisten Fällen vom Compiler automatisch korrigiert wird). In C ++ und C # ist das etwas anderes. Aber für C gibt es nur eine Bibel: "Dennis M. Ritchie: Die Programmiersprache C". Dennis (RIP!) Hat es geschrieben: "int * i". Dies muss nicht in Frage gestellt werden.

Lexi Pim
quelle
6
"In C gibt es keine Zeigertypen" - Woher kam diese Idee? int*ist ein Zeigertyp.
Keith Thompson
-2

Ich benutze, int *iweil es einfacher ist zu sehen, dass es ein Zeiger ist, obwohl ich nicht denke, dass es wirklich wichtig ist.

tia
quelle