Przegląd deklaratorów
Deklaratory są składnikami deklaracji, które określają nazwy obiektów lub funkcji.Deklaratory określają również, czy nazwany obiekt jest obiektem, wskaźnikiem, odwołaniem lub tablicą.Deklaratory nie określają typu podstawowego, ale modyfikują informacje o typie w obrębie typu podstawowego w celu określenia typów pochodnych, takich jak wskaźniki, odwołania i tablice.Deklarator w zastosowaniu do funkcji współpracuje ze specyfikatorem typu, aby w pełni określić, że typ zwracany funkcji jest obiektem, wskaźnikiem lub odwołaniem.(Specyfikatory omówione w części Deklaracje przekazują właściwości, takie jak typ i klasa magazynu.Modyfikatory omówione w tej sekcji i w części Modyfikatory specyficzne dla Microsoft modyfikują deklaratory). Na poniższej ilustracji pokazano pełną deklarację MyFunction i wywołano składniki deklaracji.
Specyfikatory, modyfikatory i deklaratory
Specyficzne dla firmy Microsoft
Większość słów kluczowych rozszerzonych przez Microsoft może być użyta jako modyfikatory do tworzenia typów pochodnych; nie są one specyfikatorami ani deklaratorami.(Zobacz Modyfikatory specyficzne dla Microsoft).
KONIEC Specyficzne dla firmy Microsoft
Deklaratory pojawiają się w składni deklaracji po opcjonalnej liście specyfikatorów.Te specyfikatory omówiono w części Deklaracje. Deklaracja może składać się z więcej niż jednego deklaratora, ale każdy deklarator deklaruje tylko jedną nazwę.
Poniższa przykładowa deklaracja pokazuje, jak specyfikatory i deklaratory są połączone, tworząc pełną deklarację:
const char *pch, ch;
W powyższej deklaracji, słowa kluczowe const i char stanowią listę specyfikatorów.Wymienione są dwa deklaratory: *pch i ch.Deklaracja, która deklaruje wiele jednostek składa się ze specyfikatora typu, po którym następuje lista deklaratorów oddzielonych przecinkami, zakończona średnikiem.
Deklaratory dla prostych obiektów
Deklarator prostego obiektu, takiego jak int lub double, jest po prostu jego nazwą z opcjonalnymi nawiasami.
int i; // declarator is i
int (i); // declarator is (i)
Deklaratory dla wskaźników, odwołań i tablic
Operatory wskaźników wstawione przed nazwą powodują, że obiekt jest wskaźnikiem lub odwołaniem.* Operator deklaruje nazwę jako wskaźnik; & operator deklaruje go jako odwołanie.
int *i; // declarator is *i
int **i; // declarator is **i;
int &i = x; // declaratory is &i
Dołączenie const lub volatile nadaje wskaźnikowi specjalne właściwości.Użycie tych specyfikatorów w deklaratorze (w przeciwieństwie do użycia w specyfikatorze typu) modyfikuje właściwości wskaźnika, a nie obiektu wskazywanego:
char *const cpc; // const pointer to char
const char *pcc; // pointer to const char
const char *const cpcc; // const pointer to const char
Dodatkowe informacje można znaleźć w Wskaźniki const i volatile.
Wskaźnik do elementu członkowskiego klasy lub struktury jest zadeklarowany z odpowiednim zagnieżdżonym specyfikatorem nazwy:
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
Nawiasy otaczające opcjonalne wyrażenie stałe po nazwie powodują, że obiekt jest tablicą.Kolejne nawiasy deklarują dodatkowe wymiary dla tablicy.
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
Deklaratory dla funkcji
Nawiasy zawierające listę argumentów są używane po jej nazwie, aby zadeklarować funkcję.Poniżej zadeklarowano funkcję o typie zwracanym int i z trzema argumentami typu int.
int f(int a, int b, int c);
Aby uzyskać informacje dotyczące list argumentów, zobacz Deklaracje funkcji.
Wskaźniki i odwołania do funkcji deklarowane są poprzez dodawanie przed nazwą funkcji wskaźnika lub operatora odwołania, jak pokazano poniżej.Nawiasy, normalnie opcjonalne, są wymagane w celu rozróżnienia wskaźnika do funkcji od funkcji, która zwraca wskaźnik:
int (*pf)(int); // pointer to function returning int
int *f(int i); // function returning pointer to int
int (&pf)(int); // reference to function
Wskaźniki do funkcji członkowskich są rozróżniane przez zagnieżdżone specyfikatory nazwy:
int (X::* pmf)(); // pointer to member function of X returning int
int* (X::* pmf)(); // pointer to member function returning pointer to int
Zobacz również Wskaźniki do elementów członkowskich.
Funkcje i obiekty w tej samej deklaracji
Funkcje i obiekty mogą być zadeklarowane w tej samej deklaracji w następujący sposób:
int i, *j, f(int k); // int, pointer to int, function returning int
Składnia może być myląca w pewnych okolicznościach.Następująca deklaracja
int* i, f(int k); // pointer to int, function returning int (not int*)
może wyglądać jak deklaracja wskaźnika int i funkcja zwracająca int*, ale tak nie jest.To dlatego, że * jest częścią deklaratora dla i, a nie częścią deklaratora dla f.
Upraszczanie składni deklaratora z użyciem typedef
Jednakże, lepszą techniką jest użycie typedef lub kombinacji nawiasów i słowa kluczowego typedef.Należy rozważyć deklarowanie tablicy wskaźników do funkcji:
// 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];
Można zapisać równoważną deklarację bez deklaracji typedef, ale jest to na tyle skomplikowane, że możliwość błędu przekracza wszelkie korzyści:
int ( *pifnDispatchArray[7] )( char * );
Aby uzyskać więcej informacji dotyczących typedef, zobacz Specyfikator typedef.
Wskaźniki, odwołania i tablice pojedynczego typu podstawowego mogą być łączone w jednej deklaracji (rozdzielonej przecinkami), jako
int a, *b, c[5], **d, &e=a;
Bardziej złożona składnia deklaratora
Deklaratory wskaźników, odwołań, tablic i funkcji mogą być łączone do określenia takich obiektów jak tablice wskaźników do funkcji, wskaźniki do tablic, itp.
Następująca gramatyka cykliczna w pełni opisuje składnię deklaratora wskaźnika.
declarator jest zdefiniowany jako jeden z:
1. identifier
2. qualified-name
3. declarator ( argument-list ) [cv-qualfiers] [exception-spec]
4. declarator [ [ constant-expression ] ]
5. pointer-operator declarator
6. ( declarator )
- i pointer-operator jest jednym z:
* [cv-qualifiers]
& [cv-qualifiers]
:: nested-name-specifier * [cv-qualfiers]
Ponieważ deklarator może składać się z deklaratorów, istnieje możliwość konstruowania bardziej złożonych typów pochodnych, takich jak tablice wskaźników, funkcji zwracających tablice wskaźników do funkcji, używając powyższych reguł.Aby wykonać każdy krok konstrukcji, rozpocznij od identyfikatora reprezentującego podstawowy typ danych i zastosuj powyższą regułę dotyczącą składni, przy poprzednim wyrażeniu będącym declarator.Kolejność stosowania reguł dotyczących składni powinna być odwrotnością sposobu, w jaki określono wyrażenie w języku angielskim.W razie zastosowania reguły składni pointer-operator dla wyrażenia tablicy lub funkcji, należy użyć nawiasów, aby uzyskać wskaźnik do tablicy lub funkcji, jak w ostatnim wierszu w tabeli poniżej.
W poniższym przykładzie pokazano konstrukcję „wskaźnika do tablicy 10 wskaźników do int”.
Ustne wyrażenie |
Deklarator |
Zastosowana reguła składni |
---|---|---|
|
1 |
|
wskaźnik(i) do |
|
5 |
tablicy 10 |
|
4 |
wskaźnik do |
|
6, a następnie 5 |
Gdy używa się wielokrotnych modyfikatorów wskaźników, odwołań, tablic lub funkcji, deklaratory mogą stać się dość skomplikowane.Rozdział Interpretowanie deklaratorów bardziej złożonych opisuje jak odczytywać bardziej złożoną składnię deklaratorów.Temat ma zastosowanie zarówno do języka C jak i C++, mimo że w języku C++ wszędzie tam, gdzie używa się * do wskazania wskaźnika, kwalifikowana nazwa taka jak MyClass::* może być użyta do określenia wskaźnika do elementu członkowskiego klasy.