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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Informaticien
    Inscrit en
    Octobre 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : Suisse

    Informations professionnelles :
    Activité : Informaticien

    Informations forums :
    Inscription : Octobre 2014
    Messages : 4
    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 confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 748
    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 748
    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
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 391
    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 Expert

    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
    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 très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    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 : 548
    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

  6. #6
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    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 202
    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"

  7. #7
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2015
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2015
    Messages : 33
    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!

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 391
    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.

  9. #9
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2015
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2015
    Messages : 33
    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