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 :

Structure et pointeur.


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2006
    Messages
    111
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2006
    Messages : 111
    Par défaut Structure et pointeur.
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    // Definition structure.
    typedef struct Point Point;
    typedef struct Mouv Mouv;
    typedef struct Unit Unit;
    // Strucutre
    struct Point
    {
    	short int unsigned x;
    	short int unsigned y;
    };
    struct Mouv
    {
    	char vue;// Orientation
    	Point deb;// Depart
    	Point go;// Destination
    	char pas;// Etape du mouvement accomplit
    };
     
    struct Unit
    {
    	short int unsigned user_id;
    	short int unsigned type;
    	Mouv mouv;
    	short int unsigned vie_act;
    	char action;
    };
    // Initialisation :
    void init_unit(short int unsigned user_id, short int unsigned type,
    		short int unsigned posi_x, short int unsigned posi_y,
    		Unit* unit_return){
     
    	unit_return	=malloc(	sizeof(short int unsigned)*3
    +sizeof(char)*3
    +sizeof(short int unsigned)*4
    	);
     
    	*unit_return.user_id	=user_id;// ERR Ici
    /*
    	unit_return->type	=type;
    	unit_return->vue	=VUE_NULL;
    	unit_return->deb.x	=posi_x;
    	unit_return->deb.y	=posi_y;
    	unit_return->go.x	=posi_x;
    	unit_return->go.y	=posi_y;
    	unit_return->pas	=0;
    	unit_return->vie_act	=1;// Vie Max a faire
    	unit_return->action	=ACT_WAIT;
    */
    printf("%p --> %s\n",unit_return,unit_return);
    return;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // Erreur -->
    didungar@DidUngar:/media/sda3/Prog/Garganthum$ gcc*
    unit.c: Dans la fonction «init_unit» :
    unit.c:14: erreur: request for member «user_id» in something not a structure or union
    // Mon but :
    Je cherche a crée de la place disponible dans tout mon programme ( d'ou mem alloc )
    Que je pourré acceder simplement grace a une structure.
    ( pas si simple que ca ... )
    j'ai donc un pointeur vers ma structure,
    et je désire l'utiliser pour aller sur mon mem alloc.

    Voila si quelqu'un pourrez m'aider ...
    Merci d'avance

  2. #2
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *unit_return.user_id = user_id;
    Non, plutôt:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unit_return->user_id = user_id;
    De plus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    unit_return = malloc (
       sizeof (short int unsigned) *3
       + sizeof (char) * 3
       + sizeof (short int unsigned) * 4
    	);
    En réalité, un char vaut toujours 1 donc un sizeof n'a que peut d'importance et même de but dans ce cas

    Pour finir:
    Ceci:
    devrait suffir !
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  3. #3
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Juste un conseil en passant sur une partie que je viens de voir:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void init_unit(short int unsigned user_id, short int unsigned type,
    		short int unsigned posi_x, short int unsigned posi_y,
    		Unit* unit_return)
    En fait, je fairais plutôt retourner un pointeur de ce type par la fonction ce qui nous donne alors:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Unit * init_unit(short int unsigned user_id, short int unsigned type,
    		short int unsigned posi_x, short int unsigned posi_y)
    L'avantage est que c'est que ca te permet également de faire retourner un code d'erreur donc ici NULL si l'allocation devais échouer (enfin il faut tout de même gérer cette éventualité mais c'est simple)
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  4. #4
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    unit_return = malloc (
       sizeof (short int unsigned) *3
       + sizeof (char) * 3
       + sizeof (short int unsigned) * 4
    	);
    Oula la pourquoi faire simple ?

    Essaye plutôt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unit_return = malloc (sizeof(struct Unit));
    Car sinon (en plus) tu risques d'avoir de grosses suprises en cas de mauvais alignement mémoire.

  5. #5
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Citation Envoyé par mchk0123
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    unit_return = malloc (
       sizeof (short int unsigned) *3
       + sizeof (char) * 3
       + sizeof (short int unsigned) * 4
    	);
    Oula la pourquoi faire simple ?

    Essaye plutôt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unit_return = malloc (sizeof(struct Unit));
    Car sinon (en plus) tu risques d'avoir de grosses suprises en cas de mauvais alignement mémoire.
    Je dirais même mieux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unit_return = malloc (sizeof(* unit_return));
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  6. #6
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    Citation Envoyé par Franck.H
    Je dirais même mieux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unit_return = malloc (sizeof(* unit_return));
    Me suis toujours demandé s'il y avait une différence en termes de code compilé, entre les 2 versions ? Je suppose que non ...

  7. #7
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Citation Envoyé par mchk0123
    Me suis toujours demandé s'il y avait une différence en termes de code compilé, entre les 2 versions ? Je suppose que non ...
    non aucune différence mais c'est surtout pour la maintenance du code. De cette manière, si le type de unit_return change et bien tu n'as pas à changer dans tout le code, juste dans sa déclaration
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  8. #8
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par mchk0123
    Me suis toujours demandé s'il y avait une différence en termes de code compilé, entre les 2 versions ? Je suppose que non ...
    Non, la différence est au niveau de la maintenance, plus aisée avec la version de Franck.

    EDIT: grillé

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  9. #9
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Pour revenir à la fonction init_unit, d'un point de vue conception, les versions données plus-haut initialisent tous les membres explicitement, y compris le champ mouv, et les champs deb et go de mouv. En procédant de la sorte, on casse l'abstraction autour des structures Mouv et Point. A mon avis, une bonne pratique est de créer un constructeur pour chacune de ces structures:

    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
    /* N'effecture pas d'allocation */
    int Point_init(Point *p_self, unisgned int x, unsigned int y)
    {
        err = 0;
     
        if (self != NULL)
        {
            /* FACULTATIF: C'est un bonne pratique de tout initialiser à 0 */
            static Point tmp = {0};
            *p_self = tmp;
     
            p_self->x = x;
            p_self->y = y;
        }
        else
        {
            /* Erreur: NULL est passé en 1er argument... */
            err = 1;
        }
        return err;
    }
    ou
    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
    /* Alloue dynamiquement de la mémoire */
    Point * Point_new(unsigned int x, unsigned int y)
    {
        Point *p_this = malloc(sizeof *p_this);
        if (p_this != NULL)
        {
            /* FACULTATIF: C'est un bonne pratique de tout initialiser à 0 */
            static Point tmp = {0};
            *p_this = tmp;
     
            p_this->x = x;
            p_this->y = y;
        }
        return p_this;
    }
    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  10. #10
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Il est essentiel de comprendre qu'en C, le passage des arguments à une fonction se fait par valeur. Ainsi, l'interface suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void init_unit(short int unsigned user_id, short int unsigned type,
                   short int unsigned posi_x, short int unsigned posi_y,
                   Unit *unit_return);
    ne fonction que si la mémoire pour unit_return est allouée à l'extérieur de la fonction. Si la fonction a la responsabilité d'allouer dynamiquement la mémoire pour cette structure à l'aide de malloc, on a deux solutions:
    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
    Unit * init_unit(short int unsigned user_id, short int unsigned type,
                   short int unsigned posi_x, short int unsigned posi_y)
    {
        Unit *unit_return = malloc(sizeof *unit_return);
        /*-TC- Il faut toujours vérifier la valeur de retour de malloc */
        if (unit_return != NULL)
        {
            unit_return->user_id = user_id;
            unit_return->type = type;
            unit_return->mouv.vue = VUE_NULL;
            unit_return->mouv.deb.x	= posi_x;
            unit_return->mouv.deb.y	= posi_y;
            unit_return->mouv.go.x = posi_x;
            unit_return->mouv.go.y = posi_y;
            unit_return->mouv.pas = 0;
            unit_return->vie_act = 1;
            unit_return->action	= ACT_WAIT;
        }
        return unit_return;
    }
    ou encore
    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
    34
    35
    36
    37
    38
    39
    enum {INIT_OK, INIT_NULL_ARG_ERROR, INIT_ALLOC_ERROR}
     
    int init_unit(short int unsigned user_id, short int unsigned type,
                     short int unsigned posi_x, short int unsigned posi_y
                     Unit **unit_return)
    {
        int err = INIT_OK;
     
        if (unit_return != NULL)
        {
            Unit *tmp = malloc(sizeof *unit_return);
            /*-TC- Il faut toujours vérifier la valeur de retour de malloc */
            if (unit_return != NULL)
            {
                tmp->user_id = user_id;
                unit_return->type = type;
                tmp->mouv.vue = VUE_NULL;
                tmp->mouv.deb.x	= posi_x;
                tmp->mouv.deb.y	= posi_y;
                tmp->mouv.go.x = posi_x;
                tmp->mouv.go.y = posi_y;
                tmp->mouv.pas = 0;
                tmp->vie_act = 1;
                tmp->action	= ACT_WAIT;
            }
            else
            {
                /* Erreur: L'allocation de mémoire à échoué */
                err = INIT_ALLOC_ERROR;
            }
            *unit_return = tmp;
        }
        else
        {
            /* Erreur: NULL passé en argument à unit_return */
            err = INIT_NULL_ARG_ERROR;
        }
        return err;
    }
    Par ailleurs, n'oublie pas qu'il faut toujours (!) vérifier la valeur de retour de malloc.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

Discussions similaires

  1. Structures et pointeurs
    Par Tchetch dans le forum C
    Réponses: 14
    Dernier message: 19/10/2006, 13h30
  2. Structure et pointeur
    Par Nalido dans le forum C
    Réponses: 5
    Dernier message: 08/08/2006, 15h08
  3. Copie de structure par pointeur - Problème LSB MSB
    Par the_ionic dans le forum Réseau
    Réponses: 4
    Dernier message: 17/07/2006, 15h08
  4. Structures et pointeurs
    Par mastochard dans le forum C
    Réponses: 17
    Dernier message: 25/05/2006, 11h55
  5. [structure et pointeur] problème d'affichage
    Par kitsune dans le forum C
    Réponses: 17
    Dernier message: 22/03/2006, 22h20

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