Comment initialiser une structure conformément aux normes du langage de programmation C
je veux initialiser un élément de structure, divisé en déclaration et initialisation. C'est ce que j'ai:
typedef struct MY_TYPE {
boolean flag;
short int value;
double stuff;
} MY_TYPE;
void function(void) {
MY_TYPE a;
...
a = { true, 15, 0.123 }
}
est la façon de déclarer et d'initialiser une variable locale de MY_TYPE
conformément aux normes de langage de programmation C (C89, C90, c99, C11, etc.)? Ou y a-t-il quelque chose de mieux ou du moins qui fonctionne?
Update j'ai fini par avoir un élément d'initialisation statique où je règle chaque subelement selon mes besoins.
13 réponses
dans (ANSI) C99, vous pouvez utiliser un initialiseur désigné pour initialiser une structure:
MY_TYPE a = { .flag = true, .value = 123, .stuff = 0.456 };
Edit: les autres membres sont initialisés comme zéro: "les membres de champ omis sont implicitement initialisés de la même façon que les objets qui ont une durée de stockage statique."( https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html )
vous pouvez le faire avec un composé littéral . Selon cette page, il fonctionne en C99 (qui compte également comme ANSI C ).
MY_TYPE a;
a = (MY_TYPE) { .flag = true, .value = 123, .stuff = 0.456 };
...
a = (MY_TYPE) { .value = 234, .stuff = 1.234, .flag = false };
les désignations dans les initialisateurs sont optionnelles; vous pouvez aussi écrire:
a = (MY_TYPE) { true, 123, 0.456 };
...
a = (MY_TYPE) { false, 234, 1.234 };
je vois que vous avez déjà reçu une réponse sur ANSI C 99, donc je vais jeter un os sur ANSI C 89. ANSI C 89 vous permet d'initialiser une structure de cette façon:
typedef struct Item {
int a;
float b;
char* name;
} Item;
int main(void) {
Item item = { 5, 2.2, "George" };
return 0;
}
une chose importante à retenir, au moment où vous initialisez même un objet/ variable dans la structure, toutes ses autres variables seront initialisées à la valeur par défaut.
si vous n'initialisez pas les valeurs dans votre struct, toutes les variables contiendront des"valeurs d'ordures".
bonne chance!
tu l'as presque...
MY_TYPE a = { true,15,0.123 };
Rapide recherche sur les 'struct initialiser c' montre-moi ce
comme Ron Nuni a dit:
typedef struct Item {
int a;
float b;
char* name;
} Item;
int main(void) {
Item item = {5, 2.2, "George"};
return 0;
}
une chose importante à retenir: au moment où vous initialisez même un objet/variable dans la structure, toutes ses autres variables seront initialisées à la valeur par défaut.
si vous n'initialisez pas les valeurs dans votre struct (i.e. si vous déclarez juste cette variable), toutes les variable.members
contiendront des" valeurs d'ordures", seulement si la déclaration est locale!
si la déclaration est globale ou statique (comme dans ce cas), tous les non-initialisés variable.members
seront initialisés automatiquement à:
-
0
pour entiers et points flottants -
'"151940920"'
pourchar
(bien sûr, c'est la même chose que0
, etchar
est un type entier) -
NULL
pour pointeurs.
C programming language standard ISO / IEC 9899: 1999 (communément appelé C99) permet d'utiliser un initialiseur désigné pour initialiser les membres d'une structure ou d'une union comme suit:
MY_TYPE a = { .stuff = 0.456, .flag = true, .value = 123 };
il est défini dans paragraph 7
, section 6.7.8 Initialization
de la norme ISO/IEC 9899:1999 comme suit:
si un indicateur a la forme
. identificateur
ensuite, l'objet courant (défini ci-dessous) doit avoir une structure ou un type d'union et l'identificateur doit être le nom d'un membre de ce type.
noter que paragraph 9
de la même section stipule que:
sauf indication contraire expresse, aux fins de la présente sous-section, les membres non nommés d'objets de structure et de type d'union ne participent pas à l'initialisation. Les membres non nommés des objets de structure ont une valeur indéterminée même après l'initialisation.
dans la mise en œuvre GNU GCC cependant, les membres omis sont initialisés en tant que valeur de type zéro ou de type zéro. Comme indiqué dans la section 6.27 Initialisateurs désignés de la documentation GNU GCC:
les membres de champ omis sont implicitement initialisés de la même manière que les objets qui ont un stockage statique durée.
Microsoft Visual C++ compiler devrait prendre en charge les initialiseurs désignés depuis la version 2013 selon l'article de blog officiel C++ Conformance Roadmap . Le paragraphe Initializing unions and structs
de initialiseurs article sur MSDN Visual Studio documentation suggère que les membres non nommés initialisés à des valeurs appropriées de type zéro comme GNU GCC.
Nouveau ISO / IEC 9899: 2011 La norme (communément appelée C11) qui a remplacé la norme ISO/IEC 9899:1999 conserve les initialisateurs désignés dans la section 6.7.9 Initialization
. Il conserve également paragraph 9
inchangé.
void function(void) {
MY_TYPE a;
a.flag = true;
a.value = 15;
a.stuff = 0.123;
}
j'ai trouvé une autre façon d'initialiser les structures.
La structure:
typedef struct test {
int num;
char* str;
} test;
initialisation:
test tt = {
num: 42,
str: "nice"
};
selon la documentation de GCC, cette syntaxe est obsolète depuis GCC 2.5 .
Je n'ai aimé aucune de ces réponses donc j'ai fait la mienne. Je ne sais pas si C'est ANSI C ou non, C'est juste GCC 4.2.1 dans son mode par défaut. Je ne me souviens jamais de la mise entre crochets, donc je commence avec un sous-ensemble de mes données et je me bats avec les messages d'erreur du compilateur jusqu'à ce qu'il se ferme. La lisibilité est ma première priorité.
// in a header:
typedef unsigned char uchar;
struct fields {
uchar num;
uchar lbl[35];
};
// in an actual c file (I have 2 in this case)
struct fields labels[] = {
{0,"Package"},
{1,"Version"},
{2,"Apport"},
{3,"Architecture"},
{4,"Bugs"},
{5,"Description-md5"},
{6,"Essential"},
{7,"Filename"},
{8,"Ghc-Package"},
{9,"Gstreamer-Version"},
{10,"Homepage"},
{11,"Installed-Size"},
{12,"MD5sum"},
{13,"Maintainer"},
{14,"Modaliases"},
{15,"Multi-Arch"},
{16,"Npp-Description"},
{17,"Npp-File"},
{18,"Npp-Name"},
{19,"Origin"}
};
les données peuvent commencer la vie comme un fichier tab-délimité que vous recherchez-remplacer pour masser dans quelque chose d'autre. Oui, c'est Debian choses. Si une paire extérieure de {} (indiquant le tableau), puis une autre paire pour chaque structure à l'intérieur. Avec des virgules entre les deux. Mettre des choses dans un en-tête n'est pas strictement nécessaire, mais j'ai environ 50 articles dans ma structure donc je les veux dans un fichier séparé, à la fois pour garder le désordre hors de mon code et donc il est plus facile de remplacer.
Structure en C peut être déclarée et initialisée comme ceci:
typedef struct book
{
char title[10];
char author[10];
float price;
} book;
int main() {
book b1={"DS", "Ajay", 250.0};
printf("%s \t %s \t %f", b1.title, b1.author, b1.price);
return 0;
}
j'ai lu la Documentation de Microsoft Visual Studio 2015 pour initialiser les types D'agrégats pourtant, toutes les formes d'initialisation avec {...}
sont expliquées ici, mais l'initialisation avec le point, nommé" designator " n'est pas mentionnée là. Il ne fonctionne pas aussi.
la norme C99 chapitre 6.7.8 initialisation explique la possibilité des désignateurs, mais à mon avis, il n'est pas vraiment clair pour les structures complexes. Le C99 la norme pdf .
dans mon esprit, il peut être mieux de
- utilisez le
= {0};
- initialisation pour toutes les données statiques. C'est moins d'effort pour le code machine. -
utiliser des macros pour initialiser, par exemple
typedef MyStruct_t{ int x, int a, int b; } MyStruct; define INIT_MyStruct(A,B) { 0, A, B}
la macro peut être adaptée, sa liste d'arguments peut être indépendante de la structure modifiée contenu. Il est approprié que moins d'éléments soient initialisés. Il est également approprié pour la structure imbriquée. 3. Une forme simple est: initialiser dans un sous-programme:
void init_MyStruct(MyStruct* thiz, int a, int b) {
thiz->a = a; thiz->b = b; }
cette routine ressemble à ObjectOriented in C. Utilisez thiz
, pas this
pour la compiler avec C++ aussi!
MyStruct data = {0}; //all is zero!
init_MyStruct(&data, 3, 456);