Proszę wyjaśnić zasady składni i zakres "typedef"
Jakie są zasady? OTOH prosty przypadek wydaje się sugerować, że nowy typ jest ostatnią rzeczą na linii. Jak tutaj Uchar
jest nowy typ:
typedef unsigned char Uchar;
Ale wskaźnik funkcji jest zupełnie inny. Oto nowy typ pFunc
:
typedef int (*pFunc)(int);
Nie mogę wymyślić innych przykładów, ale natknąłem się na kilka bardzo mylących zastosowań.
Więc są zasady, czy ludzie po prostu powinni wiedzieć z doświadczenia, że tak się to robi, ponieważ widzieli to w ten sposób wcześniej?
Również: jaki jest zakres typedef
?
2 answers
Zasadniczo typedef
ma dokładnie taką samą składnię jak deklaracja obiektu, z wyjątkiem tego, że jest poprzedzona znakiem {[6] } i zmienia to znaczenie tak, że nowy identyfikator deklaruje alias dla typu, który obiekt, który zostałby zadeklarowany, gdyby była normalną deklaracją, miałby.
A typedef
jest scopedowany dokładnie tak, jak deklaracja obiektu, więc może być scopedowany lub lokalny do bloku lub (w C++) do przestrzeni nazw lub klasy.
Np.
int
:
int a;
Deklaruje typ, który jest aliasem dla int
:
typedef int a_type;
Deklaruje wskaźnik do char
:
char *p;
Deklaruje alias dla char *
:
typedef char *pChar;
Deklaruje wskaźnik funkcji:
int (*pFn)(int);
Deklaruje alias dla typu ' wskaźnik do funkcji przyjmującej int
i zwracającej int
':
typedef int (*pFunc)(int);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-12 07:39:33
Dla wygody składniowej, {[5] } jest traktowany jako specyfikator klasy pamięci , Jak extern
, static
, lub register
. Semantycznie oczywiście jest zupełnie inaczej, ale kiedy typedef
został dodany do języka, łatwiej było użyć istniejącego fragmentu gramatyki do zdefiniowania jego składni.
Dodanie static
do deklaracji obiektu nie zmienia znaczenia deklaracji z wyjątkiem , że zmienia klasę przechowywania obiektu na "static" (jeśli nie już): {]}
{
int foo; /* automatic storage duration */
static int bar; /* static storage duration */
}
Zastąpienie static
przez typedef
zmienia znaczenie deklaracji, tak że zdefiniowana nazwa nie jest nazwą obiektu, ale nazwą typu (w rzeczywistości tylko aliasem dla istniejącego typu):
typedef int baz; /* "baz" is an alias for "int" */
Ta sama składnia dotyczy bardziej złożonych deklaracji:
int (*a)[42]; /* a is a pointer to an array of 42 ints */
static int (*b)[42]; /* Same as a, but with static storage duration */
typedef int (*c)[42] /* c is an alias for the type int(*)[42], or
"pointer to array of 42 ints" */
Kiedy zdasz sobie sprawę, że typedef
został arbitralnie wepchnięty do tego samego miejsca w gramatyce zajmowanej przez extern
, static
, i register
, zrozumienie typedef
deklaracji nie jest trudniejsze (i nie jest łatwiejsze!) niż zrozumienie deklaracji obiektów. (Program cdecl
i strona internetowa są przydatne do rozpakowywania złożonych deklaracji.)
Możesz też mieć typedef
dla typu funkcji:
void func(void); /* declare func as a function */
typedef void func_type(void); /* declare func_type as a name
for a function type */
Nie można użyć typu funkcji ed do zadeklarowania lub zdefiniowania funkcji, ale można go użyć do zadeklarowania wskaźnika funkcji:
func_type *ptr = func;
Dla scope (oznaczającego obszar tekstu programu, nad którym widoczny jest zadeklarowany identyfikator), identyfikator zdefiniowany przez typedef
deklaracja ma taki sam zakres jak każdy inny zadeklarowany identyfikator. Jeśli jest zadeklarowana w obszarze pliku, poza jakąkolwiek funkcją, jest widoczna od punktu deklaracji do końca pliku. Jeśli jest zadeklarowana wewnątrz funkcji, jest widoczna od punktu, w którym jest zadeklarowana, do końca najbliższego bloku otaczającego. I jak każda deklaracja, może być ukryta przez inną deklarację o tej samej nazwie w wewnętrznym zakresie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-22 19:05:24