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?

Author: Mailerdaimon, 2010-03-11

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);
 54
Author: CB Bailey,
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.

 3
Author: Keith Thompson,
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