IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Initialiser un pointeur sur structure qui contient une structure


Sujet :

C

  1. #1
    Nouveau membre du Club
    Inscrit en
    Mai 2007
    Messages
    52
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Mai 2007
    Messages : 52
    Points : 39
    Points
    39
    Par défaut Initialiser un pointeur sur structure qui contient une structure
    Salut à toutes et à tous,

    Le titre semble un peu lourd, mais c'est exactement ce qui me pose problème à l'heure qu'il est. Il s'agit là plus d'un question de grammaire que de trouver une solution!
    Je m'explique avec le code suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    #include <stdio.h>
    #include <stdlib.h>
     
    typedef struct
    {
    	double hauteur;
    	double largeur;
    } rectangle;
     
    typedef struct
    {
    	unsigned int nbRectangles;
    	rectangle *name;
    } ensRect;
     
    int main(void)
    {
    	register unsigned int count;
    	ensRect *touslesRectangles;
     
    	if ((touslesRectangles = malloc(5*sizeof(ensRect))) == NULL)
    	{
    		return 1;
    	}
     
    	for (count=0; count<5; count++)
    	{
    		touslesRectangles[count] = {0, NULL};
    	}
     
    	return 0;
    }
    Avec ce code, le compilateur (gcc) m'indique l'erreur suivante:
    error: expected expression before ‘{’ token

    En revanche, le programme est correctement compilé si je procède à l'initialisation de la façon suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	for (count=0; count<5; count++)
    	{
    		touslesRectangles[count].nbRectangles = 0;
    		touslesRectangles[count].name = NULL;
    	}
    Quelqu'un aurait-il une explication ?

    Merci,
    Mickaël

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 400
    Points : 23 780
    Points
    23 780
    Par défaut
    Bonjour,

    Citation Envoyé par mkrzemin Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #include <stdio.h>
    #include <stdlib.h>int main(void)
    {for (count=0; count<5; count++)
    	{
    		touslesRectangles[count] = {0, NULL};
    	}
    	…
     
    }
    Tu ne peux pas remplir un tableau de cette façon : cette notation n'est valable qu'à la compilation, pour indiquer au compilateur quel doit être l'état de la mémoire occupé par ton tableau au démarrage. À l'exécution, en revanche, ce bloc ne correspond à rien. Tu remarqueras en outre qu'il n'est pas non plus typé et, donc, ne correspond pas spécialement à un ensRect plus qu'à autre chose.

    Par contre, tu peux tout-à-fait t'en servir pour déclarer une instance de ensRect et copier cette instance dans ton tableau de structures :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int main(void)
    {
    	register unsigned int count;
    	ensRect const zero = {0, NULL};
    	ensRect *touslesRectangles;
    …
     
    	for (count=0; count<5; count++)
    	{
    		touslesRectangles[count] = zero;
    	}}
    Enfin, en C, « NULL » est censé être un marqueur mais en pratique, il est pour ainsi dire toujours égal à « 0 ». Si tu veux faire un programme portable et strictement conforme à la norme, tu procèdes comme ci-dessus, sinon tu initialises directement à zéro la mémoire allouée en utilisant calloc() plutôt que malloc() (à ne pas faire systématiquement, toutefois, car effacer à chaque fois de grandes plages de mémoire est inutilement coûteux).

  3. #3
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Une alternative en C99 est de créer un objet ensRect non nommé et initialisé par tes valeurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	for (count=0; count<5; count++)
    	{
    		touslesRectangles[count] = (ensRect){0, NULL};
    	}

  4. #4
    Membre éclairé
    Avatar de Kirilenko
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 234
    Points : 807
    Points
    807
    Par défaut
    Bonjour,

    On a aussi une autre solution en C89 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    static struct s initializer;
     
    /* ... */
     
    for (/* ... */)
    {
        touslesRectangles[/* ... */] = initializer;
    }
    Le problème étant que NULL peut avoir une représentation qui n'est pas « tous-bits-0 ». Or, avec des fonctions comme memset ou calloc, on touche à du bas niveau, et le compilateur ne contrôle plus ce qu'il est en train de remplir (ce n'est qu'une grosse zone mémoire générique). Par contre, quand 0 est utilisé dans le cadre des pointeurs, le compilateur doit en théorie se charger de le convertir vers la réelle représentation qui est utilisée par la machine.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void *p = 0; /* Légal */
    Le seul cas limite est l'appel de fonctions à nombre variable d'arguments. Dans ce cas-là, il faudra transtyper la constante, sans quoi le compilateur ne pourra pas savoir qu'il s'agit d'un pointeur. Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void f(const char *fmt, ...);
    void g(void) { f (fmt, (char *)0); }
    Bonne journée !

    ÉDIT : 0 ne passe pas avec [ CODEINLINE ] ; ça donne ça : « 0 ».

  5. #5
    Nouveau membre du Club
    Inscrit en
    Mai 2007
    Messages
    52
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Mai 2007
    Messages : 52
    Points : 39
    Points
    39
    Par défaut
    les gars, ça sent la maîtrise!

    En effet, j'avais aussi remarqué, comme l'a fait remarqué diogene, qu'en typant mon initilisation, ça marchait. Je comprends maintenant son intérêt!

    Sinon, j'ai une préférence pour l'utilisation de NULL en C. Il ne correspond pas tout à fait à 0, mais plutôt à une macro définie comme ((void *)0), que tu peux toujours redéfinir pour la portabilité de ton programme! Après, tout est histoire de goût!

    Encore merci,
    Mickaël

  6. #6
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 195
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 195
    Points : 17 163
    Points
    17 163
    Par défaut
    Citation Envoyé par mkrzemin Voir le message
    les gars, ça sent la maîtrise!

    En effet, j'avais aussi remarqué, comme l'a fait remarqué diogene, qu'en typant mon initilisation, ça marchait. Je comprends maintenant son intérêt!

    Sinon, j'ai une préférence pour l'utilisation de NULL en C. Il ne correspond pas tout à fait à 0, mais plutôt à une macro définie comme ((void *)0), que tu peux toujours redéfinir pour la portabilité de ton programme! Après, tout est histoire de goût!

    Encore merci,
    Mickaël
    Redéfinir NULL? quelle horreur!

  7. #7
    Nouveau membre du Club
    Inscrit en
    Mai 2007
    Messages
    52
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Mai 2007
    Messages : 52
    Points : 39
    Points
    39
    Par défaut
    Citation Envoyé par leternel Voir le message
    Redéfinir NULL? quelle horreur!
    Ce que je voulais dire, ce n'est pas RE-définir, mais plutôt définir, tout simplement, dans l'hypothèse où il ne l'est pas!

    Mickaël

  8. #8
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 195
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 195
    Points : 17 163
    Points
    17 163
    Par défaut
    <stdlib.h> est là pour ca.
    Il définit NULL, et il ne faudrait surtout pas que ton NULL soit différent de celui-là, ca ferait désordre

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 20
    Dernier message: 19/09/2012, 15h56
  2. Réponses: 1
    Dernier message: 02/06/2009, 17h50
  3. find sur un vector qui contient une structure
    Par kunda dans le forum SL & STL
    Réponses: 14
    Dernier message: 28/04/2009, 21h35
  4. Pointeur sur les éléments d'une structure
    Par Marley_T dans le forum C
    Réponses: 16
    Dernier message: 05/05/2008, 23h31
  5. Structure qui contient une chaine
    Par mayu5 dans le forum Débuter
    Réponses: 3
    Dernier message: 21/04/2008, 11h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo