Freigeben über


Übersicht über Deklaratoren

Deklaratoren sind die Komponenten einer Deklaration, die Namen von Objekten oder Funktionen angeben. Deklaratoren geben auch an, ob das benannte Objekt ein Objekt, ein Zeiger, ein Verweis oder ein Array ist. Obwohl Deklaratoren nicht den Basistyp angeben, ändern sie die Typinformationen im Basistyp, sodass dieser abgeleitete Typen, wie Zeiger, Verweise und Arrays, angibt. Auf Funktionen angewendet arbeitet der Deklarator mit dem Typspezifizierer, um den Rückgabetyp einer Funktion vollständig als Objekt, Zeiger oder Verweis anzugeben. (Bezeichner, die in Deklarationen erläutert werden, übermitteln Eigenschaften, wie Typ und Speicherklasse. Modifizierer, die in diesem Abschnitt und in Microsoft-spezifische Modifizierer erläutert werden, ändern Deklaratoren.) Die folgende Abbildung zeigt eine vollständige Deklaration von MyFunction und ruft die Komponenten der Deklaration auf.

Bezeichner, Modifizierer und Deklaratoren

Modifizierer, Spezifizierer und Deklaratoren

Microsoft-spezifisch

Die meisten erweiterten Microsoft-Schlüsselwörter können als Modifizierer verwendet werden, um abgeleitete Typen zu bilden. Dabei handelt es sich nicht um Spezifizierer oder Deklaratoren. (Siehe Microsoft-spezifische Modifizierer)

Ende Microsoft-spezifisch

Deklaratoren erscheinen in der Syntax für Deklarationen nach einer optionalen Liste mit Spezifizierern. Diese Spezifizierer werden in Deklarationen erläutert. Eine Deklaration kann mehr als einen Deklarator enthalten, aber jeder Deklarator deklariert nur einen Namen.

Die folgende Beispieldeklaration zeigt, wie Spezifizierer und Deklaratoren kombiniert werden, um eine vollständige Deklaration zu bilden:

const char *pch, ch;

In der vorherigen Deklaration bilden die Schlüsselwörter const und char die Liste der Spezifizierer. Zwei Deklaratoren werden aufgeführt: *pch und ch. Eine Deklaration, die mehrere Entitäten deklariert, besteht aus einem Typspezifizierer, der von einer durch Trennzeichen getrennten Liste von Deklaratoren gefolgt wird, mit einem Semikolon am Ende.

Deklaratoren für einfache Objekte

Der Deklarator eines einfachen Objekts, z. B. "int" oder "double", ist einfach nur sein Namen mit optionalen Klammern.

int i; // declarator is i

int (i); // declarator is (i)

Deklaratoren für Zeiger, Verweise und Arrays

Zeigeroperatoren, die vor dem Namen eingefügt werden, bewirken, dass das Objekt zu einem Zeiger oder Verweis wird. Der *-Operator deklariert den Namen als Zeiger, der &-Operator deklariert ihn als Verweis.

int *i; // declarator is *i
int **i; // declarator is **i;
int &i = x; // declaratory is &i

Durch Anhängen von const oder volatile erhält der Zeiger diese speziellen Eigenschaften. Die Verwendung dieser Spezifizierer in einen Deklarator (im Gegensatz zur Verwendung im Typspezifizierer) ändert die Eigenschaften des Zeigers, nicht die des Objekts, auf das gezeigt wird:

char *const cpc; // const pointer to char 
const char *pcc; // pointer to const char 
const char *const cpcc; // const pointer to const char

Weitere Informationen erhalten Sie unter const- und volatile-Zeiger.

Ein Zeiger auf einen Member einer Klasse oder Struktur wird mit dem entsprechenden geschachtelten Namenspezifizierer deklariert:

int X::* pIntMember; 
int ::X::* pIntMember; // the initial :: specifies X is in global scope
char Outer::Inner::* pIntMember; // pointer to char in a nested class

Durch Klammern, die einen optionalen konstanten Ausdruck nach dem Namen einschließen, wird das Objekt zu einem Array. Aufeinander folgende Klammern deklarieren zusätzliche Dimensionen für das Array.

int i[5]; // array with five elements of type int numbered from 0 to 4
int i[]; // array of unknown size
char *s[4]; // array of pointers to char
int i[2][2]; // two dimensional array

Deklaratoren für Funktionen

Klammern, die die Argumentliste enthalten, werden nach dem Namen zum Deklarieren einer Funktion verwendet. Im Folgenden werden eine Funktion eines Rückgabetyps int und drei Argumente des Typs int deklariert.

int f(int a, int b, int c);

Weitere Informationen zu Argumentlisten finden Sie unter Funktionsdeklarationen.

Zeiger und Verweise auf Funktionen werden deklariert, indem Sie den Zeiger- oder Verweisoperator dem Funktionsnamen wie unten dargestellt voranstellen. Klammern, die normalerweise optional sind, sind erforderlich, um einen Zeiger auf eine Funktion von einer Funktion zu unterscheiden, die einen Zeiger zurückgibt:

int (*pf)(int); // pointer to function returning int
int *f(int i); // function returning pointer to int
int (&pf)(int); // reference to function 

Zeiger auf Memberfunktionen zeichnen sich durch geschachtelte Namensspezifizierer aus:

int (X::* pmf)(); // pointer to member function of X returning int
int* (X::* pmf)(); // pointer to member function returning pointer to int

Weitere Informationen erhalten Sie unter Zeiger auf Member.

Funktionen und Objekte in derselben Deklaration

Funktionen und Objekte können in der gleichen Deklaration wie folgt deklariert werden:

int i, *j, f(int k);  // int, pointer to int, function returning int

Die Syntax kann unter bestimmten Umständen irreführend sein. Die folgende Deklarierung

int* i, f(int k);  // pointer to int, function returning int (not int*)

sieht möglicherweise aus wie die Deklaration eines int-Zeigers und einer Funktion, die int* zurückgibt, ist es aber nicht. Das liegt daran, dass * Bestandteil des Deklarators für i und nicht Teil des Deklarators für f ist.

Vereinfachung der Deklaratorsyntax mit Typedef

Eine bessere Methode besteht jedoch darin, ein typedef-Schlüsselwort oder eine Kombination aus Klammern und typedef-Schlüsselwort zu verwenden. Erwägen Sie, ein Array von Zeigern auf Funktionen zu deklarieren:

//  Function returning type int that takes one 
//   argument of type char *.
typedef int (*PIFN)( char * );
//  Declare an array of 7 pointers to functions 
//   returning int and taking one argument of type 
//   char *.
PIFN pifnDispatchArray[7];

Die entsprechende Deklaration kann ohne die typedef-Deklaration geschrieben werden, aber dies ist so kompliziert, dass das Fehlerpotential jeden Nutzen übertrifft:

int ( *pifnDispatchArray[7] )( char * );

Weitere Informationen zu typedef finden Sie unter typedef-Spezifizierer.

Zeiger, Verweise und Arrays eines einzelnen Basistyps können in einer einzigen Deklaration (durch Trennzeichen getrennt) zu Folgendem kombiniert werden:

int a, *b, c[5], **d, &e=a;

Komplexere Deklaratorsyntax

  • Zeiger-, Verweis-, Array- und Funktionsdeklaratoren werden möglicherweise kombiniert, um diese Objekte als Arrays von Zeigern auf Funktionen, Zeigern auf Arrays usw. anzugeben.

  • Die folgende rekursive Grammatik beschreibt die Zeigerdeklaratorsyntax vollständig.

  • Ein declarator wird definiert als einer von:

1. identifier 
2. qualified-name 
3. declarator ( argument-list ) [cv-qualfiers] [exception-spec]
4. declarator [ [ constant-expression ] ] 

5. pointer-operator declarator 
6. ( declarator )
  • und pointer-operator ist einer von:
* [cv-qualifiers]
& [cv-qualifiers]
:: nested-name-specifier * [cv-qualfiers]

Da ein Deklarator Deklaratoren enthalten kann, ist es möglich, anhand der oben genannten Regeln komplexere abgeleitete Typen zu erstellen (z. B. Arrays von Zeigern, Funktionen, die Arrays von Funktionszeigern zurückgeben). Um die einzelnen Schritte der Konstruktion zu bilden, beginnen Sie mit dem Bezeichner, der den Basisdatentyp darstellt, und wenden Sie die Syntaxregel oben mit dem vorherigen Ausdruck als declarator an. Die Anwendung der Syntaxregeln sollte der umgekehrten Reihenfolge des Ausdrucks auf Englisch entsprechen. Wenn Sie die pointer-operator-Syntaxregel auf einen Array- oder Funktionsausdruck anwenden, verwenden Sie Klammern, wenn Sie einen Zeiger auf das Array oder die Funktion erstellen möchten (wie in der letzten Zeile in der Tabelle weiter unten).

Das folgende Beispiel zeigt die Konstruktion von "Zeiger zu Array von 10 Zeigern zu int".

Verbaler Ausdruck

Deklarator

Angewendete Syntaxregel

i

1

Zeiger auf

*i

5

Array von 10

(*i)[10]

4

Zeiger auf

*((*i)[10])

6 und anschließend 5

Wenn mehrere Zeiger-, Verweis-, Array- oder Funktionsmodifizierer verwendet werden, werden Deklaratoren möglicherweise recht kompliziert. Das Thema Interpretieren von komplexeren Deklaratoren beschreibt, wie die Syntax komplexerer Deklaratoren gelesen wird. Das Thema trifft auf C und C++ zu. Allerdings kann in C++ für * als Zeigerindikator auf einen Member einer Klasse ein qualifizierter Name wie beispielsweise MyClass::* verwendet werden.

Siehe auch

Referenz

Deklaratoren