27 votes

Partiellement de l'initialisation d'une structure C

Ce lien indique que "Lorsqu'un automatique de tableau ou de la structure est partiellement initialiseur, le reste est initialisé à 0". J'ai décidé d'essayer ce que j'ai lu et écrit le morceau de code suivant:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
    //int arr[3] = {2};  // line no. 7

    struct s {
        int si;
        int sj;
    };

    struct s myStruct;
    myStruct.si = 9;
    printf("%d\n", myStruct.sj);
}

Je ne comprends pas pourquoi 4096 (qui je crois est une certaine "déchets" de la valeur) est imprimé quand je commenter line no. 7 et je reçois 0 quand je décommentez line no. 7. Je ne pense pas que l' arr déclaration a quelque chose à voir avec main()s'activation de l'enregistrement (ou plutôt myStruct) qui devrait ressembler (à condition que nous avons line no. 7 sans commentaire):

---------------
|  Saved PC   |
---------------
|  arr[2]     |
---------------
|  arr[1]     |
---------------
|  arr[0]     |
---------------
|  si         |
---------------
|  sj         |
---------------

Quelqu'un peut-il expliquer ce que je suis en manque ici?

50voto

dbush Points 8590

Lorsque vous faites cela:

struct s myStruct;
myStruct.si = 9;

Vous n'êtes pas l'initialisation de myStruct. Vous déclarez sans un initialiseur, puis d'exécuter une instruction pour définir un champ.

Parce que la variable est initialisée, son contenu n'est pas défini, et la lecture c'est un comportement indéfini. Cela signifie que, apparemment sans rapport avec les changements peuvent modifier ce comportement. Dans votre exemple, l'ajout d'une variable supplémentaire qui s'est passé à cause myStruct.sj à 0, mais il n'y a aucune garantie que ce sera le cas.

Pour initialiser une variable, vous devez donner une valeur à l'heure qu'il est défini:

struct s myStuct = { 9 };

Celui que vous faites cela, alors vous allez voir le contenu de myStruct.sj set à 0. Ceci est garanti conformément à l'article 6.7.8 de la norme C (avec mise en avant spécifique à ce cas):

10 Si un objet qui a automatique de la durée de stockage n'est pas initialisé explicitement, sa valeur est indéterminée. Si un objet qui a statique de la durée de stockage n'est pas initialisé explicitement, alors:

-si elle est de type pointeur, il est initialisé à null pointeur;

-si c'est de l'arithmétique, il est initialisé à (positif ou non signé) zéro;

-si c'est un agrégat, chaque membre est initialisé (de manière récursive) selon les présentes règles;

-si c'est une union, la première nommé membre est initialisé (de manière récursive) conformément à ces règles.

...

21 Si il y a moins d'initialiseurs dans un corset-ci-joint la liste de, il y sont des éléments ou des membres d'un agrégat, ou moins de caractères dans un un littéral de chaîne utilisée pour initialiser un tableau de taille connue qu'il n'y en sont des éléments dans le tableau, le reste de la somme doit être initialisé implicitement le même que les objets qui ont statique durée de stockage.

15voto

Sourav Ghosh Points 54713

Dans votre cas,

 myStruct.si = 9;

est une affectation de déclaration, pas d'initialisation. Dans ce cas, la variable de structure (et les variables correspondantes) ne sont pas initialisées. Ainsi, vous êtes en terminant la lecture de la valeur d'une variable non initialisée sj, ce qui conduit à un comportement indéfini.

Vous pouvez essayer

struct s myStruct = {9};

pour voir l' initialisation implicite dans l'action.

11voto

Quentin Points 3904

Ce n'est pas un initialiseur -- votre structure est non initialisée, vous pouvez ensuite affecter seulement si. sj reste non initialisée.

Le livre est en se référant à ce genre de code:

struct s myStruct = {9};

... où est - sj est garanti pour être 0.

2voto

sjsam Points 186

Ce qui est essentiellement une - plus-ou-moins - exemple complet pour les grandes réponses d'autres ont déjà fait.

#include<stdio.h>

struct{
  int a;
  int b;
}obj1={.a=0}; //Partial initialization

typedef struct struct_B{
  int a;
  int b;
}struct_B;

int main(void)
{
  printf("obj1.b : %d\n",obj1.b);
  struct_B obj2={.b=1,.a=0,0}; // b's first value is overridden here as 0 immediately follows a
  printf("obj2.b : %d\n",obj2.b);
  struct_B obj3={0}; //Partial initialization, here the '0' value is meant for a as it comes first in the declaration
  printf("obj3.b : %d\n",obj3.b);
  struct_B obj4={.a=0}; //Partial initialization
  printf("obj4.b : %d\n",obj4.b);
  return 0;
}

Sortie:

obj1.b : 0
obj2.b : 0
obj3.b : 0
obj4.b : 0

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X