2010-04-24 15 views
28

in C++, die folgenden Mittel "Speicher zuordnen für einen int pointer":Type Declaration - Pointer Asterisk Position

int* number; 

So, das Sternchen ein Teil der variablen Typ ist; ohne es würde das bedeuten "Speicher für einen Int zuweisen".

Wäre es dann nicht sinnvoller, wenn das Folgende bedeuten würde "Speicher für zwei int-Zeiger zuweisen"?

int* number1, number2; 
+0

möglich duplicate of http://stackoverflow.com/questions/377164/whats-your-preferred-pointer-declaration-style-and-why –

+4

[Stroustrups Antwort] (http://www.stroustrup.com/bs_faq2 .html # whitespace) für dieselbe Frage. – legends2k

Antwort

48

Stroustrup wurde dieser gefragt, und er sagte (paraphrasieren)

  • , wenn Sie mehr C-ish denken Sie int * a und Mitarbeiter sagen * pE (so im Kopf Sie ‚re denken " um den Inhalt von ein eine ganze Zahl")
  • , wenn Sie mehr C++ denken - ish werden Sie int sagen * a und Mitarbeiter * pE (so im Kopf, es ist „ein eine ganze Zahl Zeiger“)

Sie denken können, wie Sie wollen, solange Sie nie zwei ponters auf der gleichen Linie erklären.

Funktioniert für mich. Ich bin eine Employee* pE Art von Person, aber ich bin verheiratet mit einer Art von Person Employee *pE - mein Rat wäre nicht, sich darüber zu aufregen.

+1

siehe http://www.stroustrup.com/bs_faq2.html#whitespace für Referenz – Slava

20

Eigentlich das Sternchen auf die Variable (eine Konvention übernommen von C) angebracht ist, so

int * number1, number2; 

erklärt number1 als Zeiger auf int (dh *number1 ist ein int) und number2 als int.

Der Abstand hat keinen Einfluss darauf, wie die number eingegeben werden. Es dient nur als Token-Trennzeichen. Alle folgenden Aussagen sind für den Compiler identisch, da die Leerzeichen nach der Analyse entfernt werden.

int *a; 
int*a; 
int* a; 
int * a; 
int/**a***/*/*a***/a; 

Verwenden

int* number1, *number2; 

zwei Zeiger zu erstellen, oder noch besser, spaltete es in mehrere Erklärungen Verwirrung zu vermeiden. No

int* number1; 
int* number2; 
+0

Danke, aber ich frage nicht, wie ich es schreiben soll. Ich frage mich, warum der Compiler so konzipiert ist. Was macht diese Syntax logischer? – Feyyaz

+10

@sahs: Es gibt keinen guten Grund, es so zu machen, außer "es war schon immer so". Dies ist nicht so logisch, es ist _historical_ stattdessen. C, von dem wir diese Deklarationssyntax geerbt haben, ist 40 Jahre alt und älter als ein Großteil von dem, was heutzutage als gutes Sprachdesign angesehen wird. – sbi

3

,

int* number1, number2; 

erklärt number1 als Zeiger auf int und number2 als int. Persönlich ziehe ich auch den Stern auf der Art angebracht, die aus genau dem Gotcha leidet man in dieser Frage bringen, so würde ich zwei Zeiger wie folgt deklarieren:

int* number1; 
int* number2; 
8

Dies ist nur eine der vielen Unregelmäßigkeiten C-Deklarationssyntax. Der Typ-Modifikator * ist Teil des Typs und gehört syntaktisch zu dem deklarierten Bezeichner.
Das gleiche gilt für & und [], BTW.

Siehe here für was * tut neben dem Ändern eines Typs.

+0

Dies ist keine Unregelmäßigkeit der C-Syntax. Dies ist Teil der regulären Syntax der Deklaration nach Verwendung. Diese Antwort basiert auf dem Missverständnis der C-Syntax, dass Deklarationen wie folgt aussehen: ' '. So funktioniert die C-Deklarationssyntax nicht, und wenn Sie denken, dass Sie immer wieder verwirrt werden und Unregelmäßigkeiten finden. – Peaker

+2

@Peaker: Ich habe gelernt, die Deklarationssyntax von C um 1992 nicht zu mögen. Ich habe vor 20 Jahren zuerst Geld verdient, indem ich C++ - Code geschrieben habe (mit Cs Deklarationssyntax). Die Tatsache, dass ich es aus Gewohnheit und regelmäßigem Gebrauch mehr als zwei Jahrzehnte verstehe (fast) sofort, und dass ich C++ liebe, hindert mich nicht daran, die Deklarationssyntax als völligen Fehlschlag zu erkennen, den man nur entschuldigen kann durch sein enormes Altertum. Auch Sie sollten lernen, zwischen dem Schlechten, an das Sie gewöhnt sind, durch ständige Entblößung und dem Guten, das sofort erkannt wird, zu unterscheiden. Lerne einfach weiter! – sbi

17

Sie vereinfachen die Struktur der C++ - Deklaration zu stark (auch wenn die von Ihnen getroffenen Punkte vollkommen logisch sind). Nur auf den ersten Blick könnte es scheinen, dass C++ - Deklaration aus Typnamen und einer Folge von durch Komma getrennten Entitätsnamen besteht, aber in Wirklichkeit in C++ (wie auch in C) besteht die Deklaration tatsächlich aus Typenname und Folge von Deklaratoren. Die vollständigen Typinformationen für eine Entität, die Sie deklarieren, werden zwischen zwei separaten Standorten aufgeteilt, und ein Teil davon ist tatsächlich ein Teil des Deklarators. Es ist genau so, wie es in C++ ist. Um die tatsächliche Struktur der Erklärung besser widerspiegeln (wie sie in der Sprache zu sehen ist), könnte es eine gute Idee, Format Erklärungen als

int *a, *b; 

dh explizit Gruppe * s mit dem Entity-Namen, nicht mit dem Typ Name. (Aber am Ende ist es eine Frage der persönlichen Präferenz.)

Warum es so in der Sprache entworfen ist, wie Sie in einem der Kommentare fragen ... Wie Sie wissen, die Teile der Deklarationssyntax, die die Art der Entität beschreiben kann auf der linken Seite des Namens (wie * und &) sowie auf seiner rechten Seite (wie () und []), wie in

int *f(), (&g)[5], h[2][2]; 
erscheinen erklärt wird

Für die Bits, die auf der rechten Seite erscheinen, ist es einfach unmöglich, es auf andere Weise zu tun. Sie haben keine andere Wahl, als mit dem Entitätsnamen und nicht mit dem Typnamen gruppiert zu werden. Man könnte weiter fragen, warum die oben genannten Erklärungen nicht in C++ durchgeführt werden als

int *() f; 
int (&)[5] g; 
int [2][2] h; 

(dh alles typbezogene erscheint auf der linken Seite in einer kompakten Gruppe) ... Nun, die Antwort auf diese Frage ist nur so ist es in C++. Der Ansatz wird von C geerbt, und dort wird oft die "Erklärung muss der Verwendung ähnlich sein" als Begründung angeführt.

P.S. Eine andere Sache zu erinnern (und was oft falsch interpretiert wird) ist, dass Qualifikationsmerkmale neben dem Typnamen in der Deklaration Teil des gemeinsamen Typ sind, nicht ein Teil des ersten einzelnen Deklarators.Zum Beispiel

int const *a, *b; 

erklärt const int *a und const int *b, nicht int *b wie manche glauben Irrigerweise. Aus diesem Grund ziehe ich persönlich die logischere

const int *a, *b; 

Ordnung (obwohl ich mit dem Namen * lieber Gruppe zugleich auch, nicht mit dem Typ) zu verwenden.

+0

Es scheint logischer, dass Sie '*', '&', '()' und '[]' mit dem Namen, wie sie beschreiben über _that_ Variable, obwohl sie ihren Typ, aber nicht den Typ aller anderen Variablen in derselben Zeile ändern; Gleichermaßen sind Qualifier mit allen Variablen verknüpft, die in dieser Zeile deklariert sind, und somit Commong, so dass sie mit dem Typ vor dem Vorkommen korrekt erscheinen. Ich habe das gemacht, ohne über die Gründe nachzudenken, jetzt weiß ich es, also werde ich weiterhin dabei bleiben, selbst auf die Gefahr hin, dass jemand mich als C-Programmierer beurteilt, der sich als C++ - Programmierer ausgibt. – legends2k

+0

Marshall Cline verwendet Sarkasmus bei der Beantwortung einer [ähnliche FAQ] (http://www.parashift.com/c++faq/void-in-param-list.html) _ (siehe gegen Ende) _ solche Vorurteile aren zu notieren richtig. – legends2k