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 :

Spécialiser une structure à partir d'une structure existante, possible ?


Sujet :

C

  1. #1
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 128
    Par défaut Spécialiser une structure à partir d'une structure existante, possible ?
    Bonsoir,

    Ma question est la suivante :
    > J'ai une structure A.
    Je souhaite définir une structure B qui est une spécialisation de la structure A.
    Est-ce possible sans devoir définir la structure A dans celle de B ? Si oui, comment ?

    Prenons un exemple.
    J'ai une structure POINT2D qui est définie ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct POINT2D
    {
    	int x;
    	int y;
    } POINT2D;
    Je veux définir POINT3D à partir de POINT2D. Donc quelque chose de ce style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct POINT3D
    {
    	POINT2D;
    	int z;
    } POINT3D;
    Mais bon, j'ai beau essayé pleins de petites combinaisons possible et chercher sur internet, je ne trouve pas :s

    Merci

  2. #2
    Membre averti
    Homme Profil pro
    Autodidacte
    Inscrit en
    Janvier 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 30
    Par défaut
    En fait on peut voir une structure comme un type de variable personnalisé et comme toutes variables pour en créer une il faut lui donner un nom.
    Voici un exemple:

    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
     
    typedef struct POINT2D
    {
    	int x;
    	int y;
    } POINT2D;
     
    typedef struct POINT3D
    {
    	POINT2D point2d;  //creation d'une variable de type POINT2D
    	int z;
    } POINT3D;
     
    int main()
    {
    POINT3D point3d;  //creation d'une variable de type POINT3D
     
    point3d.point2d.x=10; //x
    point3d.point2d.y=20; //y
    point3d.z=30; //z
     
    printf("x=%d y=%d z=%d", point3d.point2d.x, point3d.point2d.y, point3d.z);
     
    return 0;
    }

  3. #3
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 128
    Par défaut
    Merci debian21. Cependant, cela ne répond pas à ma question ^^
    Je sais que l'on peut définir un champ possédant une structure définie auparavant.
    Ma question vise à savoir si il est possible de spécialiser une structure à partir d'une autre.
    Donc dans mon exemple, si je définissais POINT3D comme désiré, je pourrais effectuer ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    POINT3D p;
    p.x = 0;
    p.y = 1;
    p.z = 2;

  4. #4
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Bonsoir,

    tu veux faire de la poo avancée sous c ?
    C'est faisable mais ça demande pas mal de gymnastique et de rigueur, c'est souvent casse-gueule.

    Avec gcc tu as l'option -fms-extensions. Cette option avec le fait que la norme impose que l'adresse du premier membre d'une structure soit également l'adresse de la structure (pas de padding pour le premier membre) te permet de créer des sources comme :
    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
    #include <stdio.h>
     
    struct point_2d {
      int x;
      int y;
    };
     
    struct point_3d {
      struct point_2d;
      int z;
    };
     
    void print_point2d( struct point_2d* point)
    {
      printf("(%d,%d)\n", point->x, point->y);
    }
     
    void print_point3d( struct point_3d* point)
    {
      printf("(%d,%d,%d)\n", point->x, point->y, point->z);
    }
     
    int main()
    {
     
      struct point_3d p3d={1,2,3};
      struct point_2d p2d={-1,-2};
     
      print_point2d(&p2d);
      print_point3d(&p3d);
      print_point2d((struct point_2d*) &p3d);
     
      return 0;
    }
    Tu peux compiler ce source avec gcc -o oop -fms-extensions -Wall -Wextra oop.c. À l'exécution on obtient ce qu'on attendait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    > ./oop 
    (-1,-2)
    (1,2,3)
    (1,2)
    Si tu veux pousser ça encore plus loin, tu peux jeter un coup d’œil aux techniques utilisées par la GLib et ses GObjects.

  5. #5
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 128
    Par défaut
    Merci pour ta réponse kwariz.

    J'ai une structure PERSONNE(nom, prenom, age), et ça m'embêtait de devoir la définir à chaque fois pour mes autres structures EMPLOYE, AVOCAT, ..
    Du coup je cherchais une méthode plus jolie.

    Avec l'option -fms-extensions, c'est facilement réalisable

    J'imagine que sans cette option, il n'y a pas d'autres moyen de faire la même chose ?

  6. #6
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    J'imagine que tu ta phase de conception a donné quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    struct personne { .... };
    struct employe {
      struct personne;
      ....
    };
     
    struct avocat {
      struct employe;
      ...
    };
    Pourquoi pas ... c'est une possibilité.
    Une autre serait de nommer les membres et d'ajouter des accesseurs pour pouvoir utiliser les fonction sur le membre, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct employe {
      struct personne info_personne;
      ...
    }
    ....
    struct personne* employe_get_info_personne(struct employe*);
    Une autre serait de définir un enum et une «super structure» qui serait l'aggrégation de tous les champs que tu peux définir. L'enum t'indiquerait quels champs sont valides :

    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
    enum info_type { T_PERSONNE, T_EMPLOYE, T_AVOCAT };
     
    struct personne {
      enum info_type type;
      // Personne
      char* nom;
      char* prenom;
      // Employé
      struct personne* boss;
      int salaire;
      // Avocat
      long bonus;
      ...
    };
     
    int get_salaire(struct personne* p)
    {
      if (p->type<T_EMPLOYE) {
        erreur("Mauvais type");
      } else {
        return p->salaire;
      }
    }
    Il y a une tonne de possibilité ...

    Après c'est plus une question de goût, d'idiomes locaux, de choix de lisibilité/performance ...
    Les structures anonymes dans les structures sont autorisées par la norme C11, alors pourquoi pas ...
    C'est toi qui vois

  7. #7
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 128
    Par défaut
    Merci pour ta réponse

    Je vais opter pour l'extension, elle est plus pratique

  8. #8
    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 : 47
    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
    Je squat un peu le sujet vu que je test différentes solution pour mon implémentation que tu connais maintenant kwariz mais autant ton exemple fonctionne que le miens non :
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
     
    typedef struct
    {
       int x;
    }BOject;
     
    typedef struct
    {
       BOject parent;
    }BWidget;
     
     
    int main (void)
    {
       BWidget widget = { {1} };
     
       printf ("x:%d\n", widget.x);
     
       return EXIT_SUCCESS;
    }
    certes plus court mais le principe reste le même, why ?

    Pour info:
    -------------- Build: Debug in test2 (compiler: GNU GCC Compiler)---------------

    mingw32-gcc.exe -Wextra -Wall -g -fms-extensions -c C:\Projects\test2\main.c -o obj\Debug\main.o
    C:\Projects\test2\main.c: In function 'main':
    C:\Projects\test2\main.c:21:28: error: 'BWidget' has no member named 'x'
    C:\Projects\test2\main.c:19:12: warning: variable 'widget' set but not used [-Wunused-but-set-variable]
    Process terminated with status 1 (0 minutes, 0 seconds)
    1 errors, 1 warnings (0 minutes, 0 seconds)
    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 !

  9. #9
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Hello squatter

    Oui le problème avec ton code est que tu déclares un membre nommé parent de type Boject : du coup BWidget contient un membre nommé parent et aucun membre nommé x mais parent.x.
    Pour utiliser le "-fms-extensions" il ne faut pas déclarer de membre, juste donner le type (il est impératif que ce type soit une structure et que ce soit le premier champs et il ne peut y en avoir qu'un) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef struct
    {
       BOject ;
    }BWidget;

  10. #10
    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 : 47
    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
    LE petit détail auquel je n'ai pas fait attention

    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 !

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 08/03/2010, 15h43
  2. [Batch] Créer une chaine à partir d'une variable et d'une autre chaine
    Par mlle lain dans le forum Scripts/Batch
    Réponses: 1
    Dernier message: 10/11/2009, 16h26
  3. Saisir une image à partir d'une photo ou d'une vidéo
    Par lohengrin56 dans le forum Flash/Flex
    Réponses: 0
    Dernier message: 07/07/2009, 16h17
  4. Réponses: 2
    Dernier message: 05/01/2009, 12h45
  5. Réponses: 5
    Dernier message: 22/05/2008, 14h42

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