utilisation du mot clé struct dans la déclaration de variable en C++
J'ai le sentiment que cela peut être lié à la syntaxe C, mais j'ai commencé ma vie de programmation avec C++ donc je ne suis pas sûr.
, Fondamentalement, j'ai vu ceci:
struct tm t;
memset( &t, 0, sizeof(struct tm) );
Je suis un peu confus avec cette syntaxe, car normalement je m'attendrais à ce que ce qui précède ressemble à la place à ceci:
tm t;
memset( &t, 0, sizeof(tm) );
Quelle est la différence entre les deux, et pourquoi l'ancien utilisé à la place?
Mettre à jour
La structure tm
à laquelle je fais référence est dans wchar.h
, et la définition est la suivante suit:
struct tm {
int tm_sec; /* seconds after the minute - [0,59] */
int tm_min; /* minutes after the hour - [0,59] */
int tm_hour; /* hours since midnight - [0,23] */
int tm_mday; /* day of the month - [1,31] */
int tm_mon; /* months since January - [0,11] */
int tm_year; /* years since 1900 */
int tm_wday; /* days since Sunday - [0,6] */
int tm_yday; /* days since January 1 - [0,365] */
int tm_isdst; /* daylight savings time flag */
};
6 réponses
La réponse simple est que le mot clé struct
est présent pour limiter la recherche de l'identifiant tm
aux seuls types de classes définis par l'utilisateur. Il est probablement laissé pour la compatibilité avec C, où il est nécessaire.
Contrairement à ce que disent les autres, il n'existe pas de Auto-typedef , et C et c++ ne diffèrent pas non plus par la façon dont les identifiants des types définis par l'utilisateur sont gérés. La seule différence est dans la recherche.
Vous pouvez lire plus ici
En C, les noms de balise struct ne forment pas d'identificateurs dans l'espace de nom global
struct not_a_global_identifier { /* ... */ };
Pour désigner cette structure, vous devez utiliser le mot clé struct
(pour spécifier le nom de l'espace)
struct not_a_global_identifer object;
Ou créez un nouvel identifiant, dans l'Espace nom global, avec typedef
typedef struct not_a_global_identifer { /* ... */ } global_name_space_identifier;
Il y a 4 espaces de noms en C, voir 6.2.3 dans la norme C99 :
- noms des étiquettes
- les balises des structures, des unions et des énumérations
- les membres des structures ou syndicats (pas un seul espace de nom ... autant que les structures ou les syndicats sont définis)
- espace de nom global, pour tous les autres identificateurs
C'est un programme C légal: -)
int main(void) {
typedef struct foobar { int foobar; } foobar;
foobar boo;
boo.foobar = 42;
if (boo.foobar) goto foobar;
foobar:
return 0;
}
L'utilisation de {[0] } est compatible avec C, dans lequel la déclaration d'une structure nommée "tm
" définit un type nommé "struct tm
" mais pas un nommé "tm
" (par opposition à C++, dans lequel les deux noms pour le type sont déclarés).
Les types définis par l'utilisateur ont leur propre espace identifiant, c'est-à-dire que lorsque le compilateur analyse le fichier, il stocke chaque identifiant dans son espace correspondant.
Lorsque vous faites référence à tm
, le compilateur C (en tant que c++) recherchera cet identifiant dans l'espace identifiant global. Le compilateur C++ recherchera ensuite dans l'espace identifiant des types définis par l'utilisateur s'il n'avait pas trouvé le symbole auparavant.
En gros, si vous voulez avoir le même comportement qu'en C++, ajoutez cette ligne :
typedef struct tm tm;
Vous pouvez combiner struct declaration et typedef comme ceci:
typedef struct tm { int field } tm;
Ou en utilisant une structure anonyme:
typedef struct { int field } tm;
Le même comportement s'applique pour enum
et union
:
typedef enum { VALUE } myEnum;
typedef union { int integer; char charArray[4]; } myUnion;
Dans votre exemple tm peut avoir été une structure typecasted.
Par exemple
typedef struct tm_t
{
int x;
}tm;
Et puis vous pouvez faire
tm t;
Vous pouvez voir la référence liée ci-dessous et citer à partir de là " en C, vous devez explicitement utiliser le mot-clé struct pour déclarer une structure. En C++, cela n'est pas nécessaire une fois que le type a été défini."Voir le lien pour plus d'informations et d'exemples.
Http://msdn.microsoft.com/en-us/library/64973255%28v=vs.80%29.aspx