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 :

Utiliser la valeur stockée dans une variable comme type pour déclarer une autre variable


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Informaticien
    Inscrit en
    Octobre 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : Suisse

    Informations professionnelles :
    Activité : Informaticien

    Informations forums :
    Inscription : Octobre 2014
    Messages : 4
    Points : 6
    Points
    6
    Par défaut Utiliser la valeur stockée dans une variable comme type pour déclarer une autre variable
    Bonjour,

    Je vous pose la question suivante : Est-il possible de stocker dans une variable (Ex: variableType = "int"; ), et d'utiliser
    cette variable pour déclarer une autre variable (Ex : variableType nouvelleVariable; ).
    J'ai regarder au niveau des template, des alias, du casting, du transtypage, etc... mais tout cela reste encore un peux flou.

    Merci d'avance pour vos réponses

    @+

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Je dirais de faire une espèce d'usine à base de valeurs énumérées.

    Par contre sans héritage/ classe, tu risques d'avoir du code sale avec des types void, et/ ou des switch cases partout
    Et pour l'affectation d'une valeur je ne sais pas comment faire il faut connaître le type sinon on va avoir des valeurs indéfinies (ou éventuellement utiliser des unions si c'est possible)


    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    #include <stdio.h>
    #include <stdlib.h>
     
     
    typedef enum e_MY_TYPE {
    	TYPE_UNKNOWN = 0,
    	TYPE_INT,
    	TYPE_FLOAT,
    	TYPE_CHAR,
    } MY_TYPE;
     
     
    typedef struct e_ONE_VAR {
    	void* value;
    	MY_TYPE type;	
    } ONE_VAR;
     
     
    void g_create_var(ONE_VAR* var, MY_TYPE type) {
    	if (var == NULL) { return; }
     
    	var->type = type;
     
    	switch(type) {
    	case TYPE_INT:   (var->value) = (int*)   malloc( sizeof(int) );   break;
    	case TYPE_FLOAT: (var->value) = (float*) malloc( sizeof(float) ); break;
    	case TYPE_CHAR:  (var->value) = (char*)  malloc( sizeof(char) );  break;
    	default: var->value = NULL; break;
    	}
    }
     
     
    void g_destroy_var(ONE_VAR* var) {
    	if ((var == NULL) || (var->value == NULL)) { return; }
     
    	free(var->value);
    	var->value = NULL;
    }
     
     
    void g_display_var(ONE_VAR* var) {
    	if ((var == NULL) || (var->value == NULL)) { return; }
     
    	switch(var->type) {
    	case TYPE_INT:   printf("int: %d\n",   (*((int*)   var->value))); break;
    	case TYPE_FLOAT: printf("float: %f\n", (*((float*) var->value))); break;
    	case TYPE_CHAR:  printf("char: %c\n",  (*((char*)  var->value))); break;
    	default: printf("g_display_var - Error\n"); break;
    	}
    }
     
     
    int main (int argc, char** argv)
    {
    	ONE_VAR one_int;
    	ONE_VAR one_float;
    	ONE_VAR one_unknown;
     
    	g_create_var(&one_int, TYPE_INT);
    	(*((int*) one_int.value)) = 15;
     
    	g_create_var(&one_float, TYPE_FLOAT);
    	(*((float*) one_float.value)) = 3.14159;
     
    	g_create_var(&one_unknown, TYPE_UNKNOWN);
     
    	g_display_var(&one_int);
     
    	g_display_var(&one_float);
     
    	g_destroy_var(&one_unknown);
     
    	g_destroy_var(&one_float);
     
    	g_destroy_var(&one_int);
     
    	return 0;
    }

    Édit: Pour le passage de valeurs on peut faire un truc . Le paramètre est void*: void g_set_var(ONE_VAR* var, void* value) { /*...*/ }
    • Si ton type est un type élémentaire (int, float, short, ...), tu castes ton paramètre: (*((int*) var.value)) = (int) value;
    • Il faut faire attention au long, long long, double, ... s'ils ne débordent pas. Un pointeur c'est soit 4 soit 8 octets.
    • Sinon, si c'est réellement un pointeur qu'on a alloué avec un malloc: ((my_struct*) var.value) = (my_struct*) value;

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    À ce point-là, autant utiliser des VARIANT...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    Comme l'illustrent assez bien les deux premières réponses, très intéressantes au demeurant, même avec un gros bagage technique on ne peut faire que quelque chose d'approchant la déclaration d'une variable: soit une usine à cast qui donne des sueurs froides, soit une union à tiroir imbitable, mais c'est tout. Donc je dirais que tu as surtout besoin de reformuler la logique de ton programme... Quel est le contexte dans lequel tu veux faire cette déclaration?

  5. #5
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Citation Envoyé par drdgekil Voir le message
    Bonjour,

    Je vous pose la question suivante : Est-il possible de stocker dans une variable (Ex: variableType = "int"; ), et d'utiliser
    cette variable pour déclarer une autre variable (Ex : variableType nouvelleVariable; ).
    J'ai regarder au niveau des template, des alias, du casting, du transtypage, etc... mais tout cela reste encore un peux flou.

    Merci d'avance pour vos réponses

    @+
    Bonjour
    Je pense avant tout qu'il faut revoir la logique de votre programme.
    Mais cependant, il est possible de créer un type de variable capable de prendre à la fois des entiers ou tout autres types de variable en langage C.
    Explication (l'union est facultative d'un autre point de vue).


    Code C : 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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
     
    /* 
     * File:   source.c
     * Author: SAMBIA39
     *
     * Created on 12 novembre 2015, 10:44
     * 
     * Le code-source qui suit est susceptible 
     * de comporter des erreurs.
     */
     
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    /*
     *  Variable X
     */
    typedef union u_var{
        struct{
                int _int;
                char _char;
                long _long;
                short _short;
                float _float;
                void *_p_data;
                double _double;
                unsigned int _uint;
                unsigned char _uchar;
        }x;
        /* autres possibilité */
        /* struct x *p; */
    }X_var_data;
     
     
    int main( void ){
     
        X_var_data myVar;
        char *p = malloc( 100 *sizeof(char) );
        if( (NULL) == p ){
            fprintf( stderr, "(%d)\t:%s\n\t:%s\n", errno,
                    "Erreur allocation", strerror(errno) );
            return EXIT_FAILURE;
        }
     
     
     
        myVar.x._int = 10;
        myVar.x._char = 'D';
        myVar.x._long = 1024;
        myVar.x._short = 67;
        myVar.x._float = 10.45;
        myVar.x._p_data = p;
     
        fprintf( stdout, "Val Type int\t=\t%d\n", myVar.x._int );
        fprintf( stdout, "Val Type char\t=\t%c\n", myVar.x._char );
        fprintf( stdout, "Val Type long\t=\t%ld\n", myVar.x._long );
        fprintf( stdout, "Val Type short\t=\t%hd\n", myVar.x._short );
        fprintf( stdout, "Val Type float\t=\t%fl\n", myVar.x._float );
        fprintf( stdout, "Val Type void pointeur \t=\t%p\n", myVar.x._p_data );
     
        free( myVar.x._p_data );
        myVar.x._p_data = NULL;
     
        fprintf( stdout, "\n>--------------<\n");
        fprintf( stdout, "Val Type int\t=\t%d\n", myVar.x._int );
        fprintf( stdout, "Val Type char\t=\t%c\n", myVar.x._char );
        fprintf( stdout, "Val Type long\t=\t%ld\n", myVar.x._long );
        fprintf( stdout, "Val Type short\t=\t%hd\n", myVar.x._short );
        fprintf( stdout, "Val Type float\t=\t%fl\n", myVar.x._float );
        fprintf( stdout, "Val Type void pointeur \t=\t%p\n", myVar.x._p_data );
     
        return EXIT_SUCCESS;
    }
    à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  6. #6
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    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 189
    Points : 17 141
    Points
    17 141
    Par défaut
    C'est dans l'autre sens, non? L'union dans la structure.
    Et en général, on rajoute une enum disant le type actif. C'est ce qu'on appelle une "tagged union"
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  7. #7
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Oui, mais dans le cas actuel, j'ai volontairement utilisé cette façon de faire ce qui m'évite les énumérations d'un côté et de l'autre j'ai bien une variable du type entier ou autres qui ne sont pas confondus dans une union.
    à bientôt.
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  8. #8
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    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 189
    Points : 17 141
    Points
    17 141
    Par défaut
    donc, ta variable contient simultanément un int et un long et un double ...
    Ca n'est plus une variable, mais plusieurs.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par leternel Voir le message
    Ca n'est plus une variable, mais plusieurs.
    Un bon pot-pourri des familles (ou bouquet garni pour les gastronomes )

    Niveau utilisation mémoire, il ne faut pas le mettre dans une collection ou seulement en petit nombre.

    Parce que si drdgekil veut stocker par exemple indifféremment des points 2D, points 3D, voxels

  10. #10
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Exacte, plusieurs variables de types différents dans une structure typée nous donne une variable dans lequel on a un accès individuel à une variable qui stocke la valeur correspondant à son type. Le cas void est en complément des variables ou des données particulières.
    finalement on n'a pas besoin d'allocation mémoire ni de cast sauf cas de variable pointeur void et pas d'énumération.
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  11. #11
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2015
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2015
    Messages : 33
    Points : 32
    Points
    32
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    À ce point-là, autant utiliser des VARIANT...
    Possible en C? Sur le lien il n'est question que de C++ ..


    Et je ne comprends pas quelle est l'utilité d'avoir une union à un seul champ (même si celui ci est une structure), ni d'ailleurs l'utilité d'avoir une structure à un seul champ (toujours même si celui ci est une union). Pouvez vous développer à quoi vous sert cette "encapsulation"? (Pour le cas de la structure, s'il y a une enum en plus de l'union là j'y vois un sens mais sinon ) C'est un sujet très intéressant je trouve!

    Et Sambia39, je ne comprend pas non plus la plus-valu de la structure par rapport à l'union.. Je comprend bien la différence entre les deux, mais là j'ai l'impression que vous créez un set d'une variables de chaque type, plutôt qu'une variable appartenant à un set de type, non?

    Merci pour les précisions!

  12. #12
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Le VARIANT de microsoft est parfaitement utilisable en C.

    L'union extérieur bizarre avec DECIMAL, c'est pour régler un problème spécifique au fait que ce type soit Énorme; la partie "normale" du variant c'est l'équivalent de typedef struct tagVARIANT { VARTYPE vt; union { /*blabla*/ }; } VARIANT;Après, l'utilisation du VARIANT depuis un autre compilateur peut être plus compliquée, si le compilo en question ne supporte pas les structures/unions anonymes dans les structures (j'ignore tout ce ce que le standard C a à dire à ce sujet). Mais d'un autre côté, les macros fournies avec la structures permettent d'effacer ce genre de différences.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  13. #13
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2015
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2015
    Messages : 33
    Points : 32
    Points
    32
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Le VARIANT de microsoft est parfaitement utilisable en C...
    Ok! Merci de la précision.

    Citation Envoyé par Médinoc Voir le message
    ...L'union extérieur bizarre avec DECIMAL, c'est pour régler un problème spécifique au fait que ce type soit Énorme; la partie "normale" du variant c'est l'équivalent de typedef struct tagVARIANT { VARTYPE vt; union { /*blabla*/ }; } VARIANT;Après, l'utilisation du VARIANT depuis un autre compilateur peut être plus compliquée, si le compilo en question ne supporte pas les structures/unions anonymes dans les structures (j'ignore tout ce ce que le standard C a à dire à ce sujet). Mais d'un autre côté, les macros fournies avec la structures permettent d'effacer ce genre de différences.
    En fait mes interrogations concernaient le couple union/structure présenté par Sambia39.. Mais merci encore une fois! Toute info est bonne à prendre!

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 06/07/2015, 15h04
  2. probleme:recuperer une valeur stockée dans une session
    Par oasma dans le forum Servlets/JSP
    Réponses: 6
    Dernier message: 26/03/2007, 00h38
  3. Réponses: 3
    Dernier message: 22/10/2006, 23h15
  4. Réponses: 5
    Dernier message: 05/10/2006, 10h18
  5. test d'une valeur stocké dans une table
    Par EssaiEncore dans le forum ASP
    Réponses: 3
    Dernier message: 18/02/2005, 11h39

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