Dichiarazioni typedef
La dichiarazione typedef è una dichiarazione con typedef come classe di archiviazione. Il dichiaratore diventa un nuovo tipo. È possibile usare le dichiarazioni typedef per costruire nomi più brevi o più significativi per i tipi già definiti da C o per i tipi dichiarati. I nomi di typedef consentono di incapsulare dettagli di implementazione che possono cambiare.
Una dichiarazione typedef viene interpretata come una variabile o una dichiarazione di funzione, ma l'identificatore, anziché supporre il tipo specificato dalla dichiarazione, diventa un sinonimo del tipo.
Sintassi
declaration
:
declaration-specifiers
init-declarator-list
optare ;
declaration-specifiers
:
storage-class-specifier
declaration-specifiers
optare
type-specifier
declaration-specifiers
optare
type-qualifier
declaration-specifiers
optare
storage-class-specifier
:
typedef
type-specifier
:
void
char
short
int
long
float
double
signed
unsigned
struct-or-union-specifier
enum-specifier
typedef-name
typedef-name
:
identifier
Una dichiarazione typedef non crea nuovi tipi. Crea sinonimi per i tipi esistenti o nomi per tipi che possono essere specificati in altri modi. Quando un nome di typedef viene utilizzato come identificatore di tipo, può essere combinato con certi identificatori di tipo, ma non altri. I modificatori accettabili includono const
e volatile
.
I nomi typedef condividono lo spazio dei nomi con gli identificatori ordinari. Per altre informazioni, vedere Name Spaces.) Pertanto, un programma può avere un nome typedef e un identificatore di ambito locale con lo stesso nome. Ad esempio:
typedef char FlagType;
int main()
{
}
int myproc( int )
{
int FlagType;
}
Quando si dichiara un identificatore di ambito locale con lo stesso nome di un typedef o quando si dichiara un membro di una struttura o un'unione nello stesso ambito o in un ambito interno, è necessario specificare anche l'identificatore di tipo. Nell'esempio viene illustrato questo vincolo:
typedef char FlagType;
const FlagType x;
Per riutilizzare il nome FlagType
per un identificatore, un membro della struttura o un membro dell'unione, deve essere fornito il tipo:
const int FlagType; /* Type specifier required */
Non è sufficiente dire
const FlagType; /* Incomplete specification */
perché FlagType
viene usato per far parte del tipo e non un identificatore che viene ridichiarato. Questa dichiarazione si suppone essere una dichiarazione non consentita quale
int; /* Illegal declaration */
È possibile dichiarare qualsiasi tipo con typedef
, inclusi i tipi puntatore, funzione e matrice. È possibile dichiarare un nome di typedef per un puntatore a un tipo di unione o di struttura prima di definire il tipo di struttura o di unione, purché la definizione abbia la stessa visibilità della dichiarazione.
I nomi di typedef possono essere utilizzati per migliorare la leggibilità del codice. Tutte e tre le seguenti dichiarazioni di signal
indicano esattamente lo stesso tipo, la prima senza utilizzare alcun nome di typedef.
typedef void fv( int ), (*pfv)( int ); /* typedef declarations */
void ( *signal( int, void (*) (int)) ) ( int );
fv *signal( int, fv * ); /* Uses typedef type */
pfv signal( int, pfv ); /* Uses typedef type */
Esempi
Negli esempi seguenti vengono illustrate le dichiarazioni typedef:
typedef int WHOLE; /* Declares WHOLE to be a synonym for int */
Ad esempio, WHOLE
potrebbe ora essere usato in una dichiarazione di variabile, WHOLE i;
ad esempio o const WHOLE i;
. Tuttavia, la dichiarazione long WHOLE i;
non è consentita.
typedef struct club
{
char name[30];
int size, year;
} GROUP;
Questa istruzione dichiara GROUP
come un tipo di struttura con tre membri. Poiché viene anche specificato un tag della struttura, club
, nelle dichiarazioni può essere utilizzato il nome di typedef (GROUP
) o il tag della struttura. È necessario usare la struct
parola chiave con il tag e non è possibile usare la struct
parola chiave con il nome typedef.
typedef GROUP *PG; /* Uses the previous typedef name
to declare a pointer */
Il tipo PG
è dichiarato come puntatore al tipo GROUP
, che a sua volta è definito come tipo di struttura.
typedef void DRAWF( int, int );
Questo esempio fornisce il tipo DRAWF
per una funzione che non restituisce valori e che accetta due argomenti di tipo int. Significa, ad esempio, che la dichiarazione
DRAWF box;
è equivalente alla dichiarazione
void box( int, int );