142 Stimmen

Platzierung des Sternchens in Zeigerdeklarationen

Ich habe kürzlich beschlossen, dass ich endlich C/C++ lernen muss, und es gibt eine Sache, die ich nicht wirklich über Zeiger verstehe, genauer gesagt, ihre Definition.

Wie wäre es mit diesen Beispielen?

  1. int* test;
  2. int *test;
  3. int * test;
  4. int* test,test2;
  5. int *test,test2;
  6. int * test,test2;

Nun, nach meinem Verständnis, die ersten drei Fälle sind alle das gleiche tun: Test ist nicht ein int, aber ein Zeiger auf ein.

Die zweite Gruppe von Beispielen ist etwas komplizierter. In Fall 4 sind sowohl test als auch test2 Zeiger auf einen int, während in Fall 5 nur test ein Zeiger ist, während test2 ein "echter" int ist. Was ist mit Fall 6? Dasselbe wie in Fall 5?

19 Stimmen

In C/C++ ändern Leerzeichen die Bedeutung nicht.

38 Stimmen

7. int*test; ?

4 Stimmen

+1, denn ich hatte nur daran gedacht, nach 1 - 3 zu fragen. Beim Lesen dieser Frage habe ich etwas über 4 - 6 gelernt, woran ich nie gedacht hatte.

3voto

deLock Punkte 711

Meiner Meinung nach lautet die Antwort BEIDES, je nach Situation. Im Allgemeinen ist es IMO besser, das Sternchen neben den Zeigernamen zu setzen, als den Typ. Vergleiche z.B.:

int *pointer1, *pointer2; // Fully consistent, two pointers
int* pointer1, pointer2;  // Inconsistent -- because only the first one is a pointer, the second one is an int variable
// The second case is unexpected, and thus prone to errors

Warum ist der zweite Fall inkonsistent? Weil z.B. int x,y; deklariert zwei Variablen desselben Typs, aber der Typ wird nur einmal in der Deklaration erwähnt. Dies schafft einen Präzedenzfall und ein erwartetes Verhalten. Und int* pointer1, pointer2; ist damit unvereinbar, weil sie erklärt pointer1 als Zeiger, aber pointer2 ist eine ganzzahlige Variable. Eindeutig fehleranfällig und sollte daher vermieden werden (indem das Sternchen neben den Zeigernamen gesetzt wird und nicht neben den Typ).

Allerdings gibt es einige Ausnahmen in denen es nicht möglich ist, das Sternchen neben einen Objektnamen zu setzen (und in denen es darauf ankommt, wo Sie es setzen), 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

Und schließlich könnte es in einigen Fällen durchaus sinnvoll sein Übersichtlicher um das Sternchen neben die Typ Name, z.B.:

void* ClassName::getItemPtr () {return &item;} // Clear at first sight

1voto

Ron Warholic Punkte 9894

Der Zeiger ist ein Modifikator für den Typ. Es ist am besten, sie von rechts nach links zu lesen, um besser zu verstehen, wie das Sternchen den Typ modifiziert. 'int *' kann als "Zeiger auf int" gelesen werden. Bei Mehrfachdeklarationen müssen Sie angeben, dass jede Variable ein Zeiger ist, sonst wird sie als Standardvariable angelegt.

1,2 und 3) Der Test ist vom Typ (int *). Whitespace spielt keine Rolle.

4,5 und 6) Der Test ist vom Typ (int *). Test2 ist vom Typ int. Auch hier ist das Leerzeichen unerheblich.

1voto

TallChuck Punkte 1120

Ich habe es immer vorgezogen, Zeiger auf diese Weise zu deklarieren:

int* i;

Ich lese das so: " i ist vom Typ int-Zeiger". Sie können mit dieser Interpretation auskommen, wenn Sie nur eine Variable pro Deklaration deklarieren.

Es ist jedoch eine unangenehme Wahrheit, dass diese Lesart falsch . Die Programmiersprache C, 2. Auflage. (S. 94) erklärt das entgegengesetzte Paradigma, das in den C-Standards verwendet wird:

Die Deklaration des Zeigers ip ,

int *ip;

ist als Gedächtnisstütze gedacht; er besagt, dass der Ausdruck *ip ist ein int . Die Syntax der Deklaration für eine Variable entspricht der Syntax von Ausdrücken, in denen die Variable vorkommen könnte. Diese Überlegung gilt auch für Funktionsdeklarationen. Zum Beispiel,

double *dp, atof(char *);

besagt, dass in einem Ausdruck *dp y atof(s) haben Werte vom Typ double und dass das Argument der atof ist ein Zeiger auf char .

Nach der Logik der Sprache C bedeutet die Deklaration von

int* test, test2;

deklarieren Sie nicht zwei Variablen des Typs int* führen Sie zwei Ausdrücke ein, die zu einem int Typ, ohne Bindung an die Zuordnung eines int in Erinnerung.

Ein Compiler ist durchaus in der Lage, das Folgende zu akzeptieren:

int *ip, i;
i = *ip;

denn im C-Paradigma wird vom Compiler nur erwartet, dass er den Verlauf der Typ von *ip y i . Vom Programmierer wird erwartet, dass er den Überblick über die Bedeutung von *ip y i . In diesem Fall, ip ist nicht initialisiert, so dass es in der Verantwortung des Programmierers liegt, auf etwas Sinnvolles zu verweisen, bevor es dereferenziert wird.

0 Stimmen

Interessant ist, dass die Erklärung int *ip = 0, i = 0 initialisiert ip = (int*) 0 und i = (int) 0 so dass sich die Nachahmung der Ausdruckssyntax nicht auf den Zuweisungsoperator erstreckt

-2voto

mstrobl Punkte 2341

Eine gute Faustregel, nach der viele Menschen diese Konzepte zu begreifen scheinen: In C++ wird ein Großteil der semantischen Bedeutung durch die Linksbindung von Schlüsselwörtern oder Bezeichnern abgeleitet.

Nehmen Sie zum Beispiel:

int const bla;

Das const gilt für das Wort "int". Dasselbe gilt für die Sternchen bei Zeigern, sie gelten für das Schlüsselwort links von ihnen. Und der eigentliche Variablenname? Ja, der wird durch das deklariert, was links von ihm steht.

4 Stimmen

Das ist keine Antwort auf die Frage. Schlimmer noch, wenn wir versuchen ableiten eine Antwort von ihm, dann impliziert es, dass das Sternchen an die Schrift links von ihm gebunden ist, was, wie alle anderen schon gesagt haben, falsch ist. Es bindet sich an den einzelnen Variablennamen auf der rechten Seite.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X