Ich habe kürzlich beschlossen, dass ich nur endlich C / C ++ lernen muss, und es gibt eine Sache, die ich über Zeiger oder genauer ihre Definition nicht wirklich verstehe.
Wie wäre es mit diesen Beispielen:
int* test;
int *test;
int * test;
int* test,test2;
int *test,test2;
int * test,test2;
Nach meinem Verständnis machen die ersten drei Fälle alle dasselbe: Test ist kein int, sondern ein Zeiger auf einen.
Die zweite Reihe von Beispielen ist etwas kniffliger. In Fall 4 sind sowohl test als auch test2 Zeiger auf ein int, während in Fall 5 nur test ein Zeiger ist, während test2 ein "reales" int ist. Was ist mit Fall 6? Gleich wie Fall 5?
c++
c
pointers
declaration
Michael Stum
quelle
quelle
int*test;
?Foo<Bar<char>>
der>>
musste geschrieben werden> >
, um nicht als Rechtsverschiebung behandelt zu werden.++
nicht durch ein Leerzeichen geteilt werden, Bezeichner können nicht durch ein Leerzeichen geteilt werden (und das Ergebnis kann für den Compiler weiterhin zulässig sein, jedoch mit undefiniertem Laufzeitverhalten). Die genauen Situationen sind angesichts des Syntaxproblems in C / C ++ sehr schwer zu definieren.Antworten:
4, 5 und 6 sind dasselbe, nur Test ist ein Zeiger. Wenn Sie zwei Zeiger möchten, sollten Sie Folgendes verwenden:
Oder noch besser (um alles klar zu machen):
quelle
Leerzeichen um Sternchen haben keine Bedeutung. Alle drei bedeuten dasselbe:
Das "
int *var1, var2
" ist eine böse Syntax, die nur dazu gedacht ist, Menschen zu verwirren und sollte vermieden werden. Es erweitert sich zu:quelle
int*test
.int *test
( google-styleguide.googlecode.com/svn/trunk/… ).In vielen Codierungsrichtlinien wird empfohlen, nur eine Variable pro Zeile zu deklarieren . Dies vermeidet jegliche Verwirrung, wie Sie sie vor dem Stellen dieser Frage hatten. Die meisten C ++ - Programmierer, mit denen ich gearbeitet habe, scheinen sich daran zu halten.
Ein bisschen beiseite, ich weiß, aber etwas, das ich nützlich fand, ist, Erklärungen rückwärts zu lesen.
Dies funktioniert sehr gut, insbesondere wenn Sie anfangen, const-Zeiger zu deklarieren, und es wird schwierig zu wissen, ob es der Zeiger ist, der const ist, oder ob es das ist, worauf der Zeiger auf const zeigt.
quelle
Verwenden Sie die "Spiralregel im Uhrzeigersinn" , um C / C ++ - Deklarationen zu analysieren.
Außerdem sollten Erklärungen nach Möglichkeit in separaten Aussagen enthalten sein (was in den allermeisten Fällen der Fall ist).
quelle
int* x;
eher zum Stil als zum traditionellenint *x;
Stil führt. Natürlich spielt der Abstand für den Compiler keine Rolle, aber er wirkt sich auf die Menschen aus. Das Ablehnen der eigentlichen Syntax führt zu Stilregeln, die den Leser stören und verwirren können.Wie andere erwähnt haben, sind 4, 5 und 6 gleich. Oft verwenden die Leute diese Beispiele, um das Argument zu machen, dass das
*
zur Variablen anstelle des Typs gehört. Während es sich um eine Frage des Stils handelt, gibt es einige Debatten darüber, ob Sie es so denken und schreiben sollten:oder so:
FWIW Ich bin im ersten Lager, aber der Grund, warum andere das Argument für die zweite Form vorbringen, ist, dass es (meistens) dieses spezielle Problem löst:
was möglicherweise irreführend ist; stattdessen würdest du entweder schreiben
oder wenn Sie wirklich zwei Zeiger wollen,
Persönlich sage ich, behalte es bei einer Variablen pro Zeile, dann ist es egal, welchen Stil du bevorzugst.
quelle
int *MyFunc(void)
? a*MyFunc
Gibt eine Funktion ein zurückint
? Nein. Offensichtlich sollten wir schreibenint* MyFunc(void)
und sagen, dassMyFunc
eine Funktion a zurückgibtint*
. Für mich ist klar, dass die Parsing-Regeln für C- und C ++ - Grammatik für die Variablendeklaration einfach falsch sind. Sie sollten die Zeigerqualifizierung als Teil des gemeinsam genutzten Typs für die gesamte Komma-Sequenz enthalten.*MyFunc()
aber einint
. Das Problem mit der C-Syntax besteht darin, Präfix- und Postfix- Syntax zu mischen. Wenn nur Postfix verwendet würde, würde es keine Verwirrung geben.int const* x;
, die ich ebenso irreführend finde wiea * x+b * y
.quelle
#include <windows.h>LPINT test, test2;
In 4, 5 und 6
test
ist immer ein Zeiger undtest2
kein Zeiger. Leerzeichen sind in C ++ (fast) nie von Bedeutung.quelle
Meiner Meinung nach lautet die Antwort BEIDE, je nach Situation. Im Allgemeinen, IMO, ist es besser, das Sternchen neben den Zeigernamen zu setzen, als den Typ. Vergleiche zB:
Warum ist der zweite Fall inkonsistent? Denn zB
int x,y;
deklariert zB zwei Variablen des gleichen Typs, aber der Typ wird in der Deklaration nur einmal erwähnt. Dies schafft einen Präzedenzfall und ein erwartetes Verhalten. Undint* pointer1, pointer2;
ist damit nicht vereinbar, weil espointer1
als Zeiger deklariert , aberpointer2
eine ganzzahlige Variable ist. Offensichtlich fehleranfällig und sollte daher vermieden werden (indem das Sternchen neben den Zeigernamen und nicht neben den Typ gesetzt wird).Es gibt jedoch einige Ausnahmen, bei denen Sie das Sternchen möglicherweise nicht neben einem Objektnamen platzieren können (und bei denen es darauf ankommt, wo Sie es platzieren), ohne ein unerwünschtes Ergebnis zu erhalten - zum Beispiel:
MyClass *volatile MyObjName
void test (const char *const p) // const value pointed to by a const pointer
Schließlich wird in einigen Fällen könnte es wohl sein klarer das Sternchen zu setzen neben dem Typ Namen, zB:
void* ClassName::getItemPtr () {return &item;} // Clear at first sight
quelle
Das Grundprinzip in C ist, dass Sie die Variablen so deklarieren, wie Sie sie verwenden. Beispielsweise
sagt, das
*a[42]
wird einchar
. Unda[42]
ein Zeichenzeiger. Und somita
ist ein Array von Zeichenzeigern.Dies liegt daran, dass die ursprünglichen Compiler-Autoren denselben Parser für Ausdrücke und Deklarationen verwenden wollten. (Kein sehr vernünftiger Grund für eine Wahl des Sprachdesigns)
quelle
char* a[100];
auch ab, dass*a[42];
dies einchar
unda[42];
ein Zeichenzeiger sein wird.a[42]
einchar
Zeiger und*a[42]
ein Zeichen.Ich würde sagen, dass die ursprüngliche Konvention darin bestand, den Stern auf die Zeigernamensseite (rechte Seite der Deklaration) zu setzen
In der Programmiersprache c von Dennis M. Ritchie befinden sich die Sterne auf der rechten Seite der Erklärung.
Wenn wir uns den Linux-Quellcode unter https://github.com/torvalds/linux/blob/master/init/main.c ansehen, können wir sehen, dass sich der Stern auch auf der rechten Seite befindet.
Sie können die gleichen Regeln befolgen, aber es ist keine große Sache, wenn Sie Sterne auf die Typenseite setzen. Denken Sie daran, dass Konsistenz wichtig ist, also immer, aber der Stern auf derselben Seite, unabhängig davon, welche Seite Sie gewählt haben.
quelle
Der Zeiger ist ein Modifikator für den Typ. Lesen Sie sie am besten von rechts nach links, um besser zu verstehen, wie das Sternchen den Typ ändert. 'int *' kann als "Zeiger auf int 'gelesen werden. In mehreren Deklarationen müssen Sie angeben, dass jede Variable ein Zeiger ist, sonst wird sie als Standardvariable erstellt.
1,2 und 3) Test ist vom Typ (int *). Leerzeichen spielen keine Rolle.
4,5 und 6) Test ist vom Typ (int *). Test2 ist vom Typ int. Auch hier spielt das Leerzeichen keine Rolle.
quelle
Als gute Faustregel scheinen viele Leute diese Konzepte zu verstehen, indem sie: In C ++ wird eine Menge semantischer Bedeutung durch die Linksbindung von Schlüsselwörtern oder Bezeichnern abgeleitet.
Nehmen Sie zum Beispiel:
Die Konstante gilt für das Wort "int". Das Gleiche gilt für die Sternchen der Zeiger. Sie gelten für das Schlüsselwort links von ihnen. Und der tatsächliche Variablenname? Ja, das wird durch das erklärt, was davon übrig ist.
quelle