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 :

déclaration/initialisation d'une structure


Sujet :

C

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut déclaration/initialisation d'une structure
    bonjour,

    je voudrais déclarer/initialiser une structure. Voici ce que j'ai commencé à faire pour me simplifier la vie :
    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
     
    // ******************************
    // Définition des MACROs
    #define TYPE_STR 		1
    #define TYPE_UINT32		2
     
    // ne focntionne pas => message d'erreur : on ne peut pas concatener x avec le caractère '.'
    #define CHAMPS_STR(x, y)   	\
    	.##x##.type = TYPE_STR,	\
    	.##x##.len = 30, 		\
    	.##x##.str = y	
     
    #define CHAMPS_UINT32(x, y)		\
    	.##x##.type = TYPE_UINT32,	\
    	.##x##.len = 4,				\
    	.##x##.Val = y	
     
     
     
     
    // ******************************
    // Déclaration des types
    typedef struct _TypeString {
    	UINT16	type;
    	UINT16	len;
    	UINT8	str[30];
    } typeString;
     
    typedef struct _TypeInt32 {
    	UINT16	type;
    	UINT16	len;
    	UINT32	Val;
    } typeInt32;
     
     
     
    // ******************************
    // Déclaration des types
    typedef struct _ZoneMem {
    	typeString nomPays;
    	typeString nomVille;
    	typeInt32 nombreHabitants;
     
    	// ...
    } ZoneMem;
     
     
     
     
    // ******************************
    // Declaration de l'empreinte mémoire
    /*
    ZoneMem myZone = {
    	.nomPays.type = TYPE_STR,
    	.nomPays.len = 7,
    	.nomPays.str = "France",
     
    	.nomVille.type = TYPE_STR,
    	.nomVille.len = 6,
    	.nomVille.str = "Paris",
     
    	.nombreHabitants.type = TYPE_UINT32,
    	.nombreHabitants.len = 4,
    	.nombreHabitants.Val = 123456
    };
    // */
     
    ZoneMem myZone = {
    	CHAMPS_STR(nomPays, "France"),
    	CHAMPS_STR(nomVille, "Paris"),
     
    	CHAMPS_UINT32(nombreHabitants, 123456),
    };
    J'ai deux problème :
    - Mes #define ne compilent pas tous
    - Comment faire pour ne pas avoir une taille fixe pour mes chaines afin de pouvoir optimiser la taille en fonction de la taille réelle de la chaine ?

    Comment feriez-vous ?

    merci d'avance,

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par boboss123 Voir le message
    bonjour,

    je voudrais déclarer/initialiser une structure. Voici ce que j'ai commencé à faire pour me simplifier la vie :
    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
     
    // ******************************
    // Définition des MACROs
    #define TYPE_STR 		1
    #define TYPE_UINT32		2
     
    // ne focntionne pas => message d'erreur : on ne peut pas concatener x avec le caractère '.'
    #define CHAMPS_STR(x, y)   	\
    	.##x##.type = TYPE_STR,	\
    	.##x##.len = 30, 		\
    	.##x##.str = y	
     
    #define CHAMPS_UINT32(x, y)		\
    	.##x##.type = TYPE_UINT32,	\
    	.##x##.len = 4,				\
    	.##x##.Val = y	
     
     
     
     
    // ******************************
    // Déclaration des types
    typedef struct _TypeString {
    	UINT16	type;
    	UINT16	len;
    	UINT8	str[30];
    } typeString;
     
    typedef struct _TypeInt32 {
    	UINT16	type;
    	UINT16	len;
    	UINT32	Val;
    } typeInt32;
     
     
     
    // ******************************
    // Déclaration des types
    typedef struct _ZoneMem {
    	typeString nomPays;
    	typeString nomVille;
    	typeInt32 nombreHabitants;
     
    	// ...
    } ZoneMem;
     
     
     
     
    // ******************************
    // Declaration de l'empreinte mémoire
    /*
    ZoneMem myZone = {
    	.nomPays.type = TYPE_STR,
    	.nomPays.len = 7,
    	.nomPays.str = "France",
     
    	.nomVille.type = TYPE_STR,
    	.nomVille.len = 6,
    	.nomVille.str = "Paris",
     
    	.nombreHabitants.type = TYPE_UINT32,
    	.nombreHabitants.len = 4,
    	.nombreHabitants.Val = 123456
    };
    // */
     
    ZoneMem myZone = {
    	CHAMPS_STR(nomPays, "France"),
    	CHAMPS_STR(nomVille, "Paris"),
     
    	CHAMPS_UINT32(nombreHabitants, 123456),
    };
    J'ai deux problème :
    - Mes #define ne compilent pas tous
    Désolé, je pige que dalle à tes define. Eventuellement en parsant ton source avec juste le préprocesseur (gcc -E) ça te donnera un interprété (.i) qui te montrera ce qui est compris par le compilo...

    Citation Envoyé par boboss123 Voir le message
    - Comment faire pour ne pas avoir une taille fixe pour mes chaines afin de pouvoir optimiser la taille en fonction de la taille réelle de la chaine ?

    Comment feriez-vous ?
    Tout dépend de ce que je dois stocker

    Si je veux stocker des chaines déjà écrites dans mon source (en "dur" quoi), alors je me casses pas le luc. Je ne mémoriserai que les adresses ce ces chaines et ma structure sera donc écrite dans ce sens.

    Si je veux stocker des chaines qui arrivent d'un autre flux (un fichier), alors je suis obligé de prévoir, dans ma structure, une zone de taille suffisante. Et là, 2 façons de faire
    1) tu "estimes" qu'aucune des chaines à mémoriser ne dépassera "x" octets et tu tailles ta zone en conséquence sur la taille la plus grande possible (sans oublier le "+1" pour mémoriser aussi le '\0')
    2) tu veux travailler le plus finement possible et tu alloues alors, pour chaque chaine à stocker, ta zone en dynamique avant d'y stocker la chaine en question

    Dans le cas 1, l'avantage c'est que tu ne t'embêtes pas avec l'allocation. Chaque zone peut stocker "x" caractères et les stockes même s'il n'y en a pas autant. En revanche, l'inconvénient c'est que tu peux avoir de l'espace non utilisé. Et si jamais t'as mal estimé ton besoin et que ta zone n'est pas assez grande, alors gros crash possible à plus ou moins long terme.

    Dans le cas 2, zéro soucy. Ton programme tournera sans accroc et n'utilisera que ce dont il a besoin. Mais tu auras été obligé de déployer toute une batterie d'allocation/vérification/libération lourde à mettre en oeuvre. et si tu dois stocker 10000 chaines ben ça fera quand-même 10000 opérations d'allocation qui sont aussi une charge pour le processeur.

    Voilà. A toi de voir...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    merci, ton post me donne un début de réponse mais il te manque certaines informations.

    En fait j'ai deux appareils qui communiquent entre eux. Le premier qui contient la struture l'envoie au second qui lui doit afficher toutes les variables récupérée.
    Je pensais donc d'écrire ma variable en plusieurs champs :
    - le type de variable (pour que le second module sache sous quel format afficher la valeur)
    - la taille de la variable
    - le nom de la variable => j'ai oublié de la mettre dans mon précédent post
    - la valeur de la variable

    Donc ce donne une structure du genre (pour le type string par 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
    typedef struct _TypeString {
    	UINT16	type;
    	UINT16	lenTotal;
    	UINT16	lenName; // champs optionnel : permet de pouvoir pointer plus facilement sur l'element str (evite de parcourir name)
    	UINT8	name[10];
    	UINT8	str[30]; 
    } typeString;
     
     
    // initialisation des valeur :
    .toto.type = TYPE_STR,
    .toto.lenTotal = 2 + 10 + 30,
    .toto.lenName = 10,
    .toto.name = "toto",
    .toto.str = "salut mec !"
    Donc le second module affichera :
    Donc pour la déclaration de ma structure je pensais créer des macro pour me simplifier la vie qui s'occuperait de faire l'initialisation de ma chaine :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #define CHAMPS_STR(nomVariable, valeur)
     
    // donne :
    //.nomVariable.type = TYPE_STR,
    //.nomVariable.lenTotal = 2 + 10 + 30,
    //.nomVariable.lenName = 10,
    //.nomVariable.name = nomVariable,
    //.nomVariable.str = valeur
    => c'est un exemple avec des chaine de taille fixe mais j'aimerais que ça soit dynamique

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par boboss123 Voir le message
    merci, ton post me donne un début de réponse mais il te manque certaines informations.

    En fait j'ai deux appareils qui communiquent entre eux. Le premier qui contient la struture l'envoie au second qui lui doit afficher toutes les variables récupérée.
    Ok. Donc tu dois préparer la place pour recevoir les infos lues.

    Citation Envoyé par boboss123 Voir le message
    Je pensais donc d'écrire ma variable en plusieurs champs :
    - le type de variable (pour que le second module sache sous quel format afficher la valeur)
    Ok. Ou alors un code particulier représentant le type...

    Citation Envoyé par boboss123 Voir le message
    - la taille de la variable
    - le nom de la variable => j'ai oublié de la mettre dans mon précédent post
    Important le nom ? Un nom n'est qu'un nom. Que le module 1 stocke l'age du capitaine dans une variable "ageDuCapitaine" et que le module 2 stocke la même valeur dans une variable "ageOfCaptain" n'a aucune importance...

    Citation Envoyé par boboss123 Voir le message
    - la valeur de la variable

    Donc ce donne une structure du genre (pour le type string par 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
    typedef struct _TypeString {
    	UINT16	type;
    	UINT16	lenTotal;
    	UINT16	lenName; // champs optionnel : permet de pouvoir pointer plus facilement sur l'element str (evite de parcourir name)
    	UINT8	name[10];
    	UINT8	str[30]; 
    } typeString;
     
     
    // initialisation des valeur :
    .toto.type = TYPE_STR,
    .toto.lenTotal = 2 + 10 + 30,
    .toto.lenName = 10,
    .toto.name = "toto",
    .toto.str = "salut mec !"
    Donc le second module affichera :
    Ok, je vois le truc. Bon déjà je me demande pourquoi name et str sont des tableaux UINT8. Des tableaux char aurait peut-être été plus judicieux. Mais surtout t'as pas le droit d'écrire name="toto" car là, tu ne stockes que le pointeur, c.a.d. l'adresse de ton code qui contient la chaine "toto". C'est ce que je disais en première partie de mon précédent post.
    Si la chaine "toto" vient d'ailleurs (d'une autre variable xxx qui l'aura lue dans ta socket) alors faut que tu passes par strcpy()...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Important le nom ? Un nom n'est qu'un nom.
    oui, il faut le nom de la variable car il faut que je l'affiche sur le module 2 => ex: temperature = 35°C. Par contre c'est vrai qu'il n'est pas nécessaire que le nom de la structure, soit le même que le nom de la variable

    Citation Envoyé par Sve@r Voir le message
    Ok, je vois le truc. Bon déjà je me demande pourquoi name et str sont des tableaux UINT8. Des tableaux char aurait peut-être été plus judicieux.
    => un char et un UINT8, ce n'est pas la même chose ?



    Citation Envoyé par Sve@r Voir le message
    Mais surtout t'as pas le droit d'écrire name="toto" car là, tu ne stockes que le pointeur, c.a.d. l'adresse de ton code qui contient la chaine "toto". C'est ce que je disais en première partie de mon précédent post.
    oups effectivement ce n'est pas bon... je ne vois pas trop comment faire alors (je voudrais pouvoir balancer les valeurs de ma structure sans a voir à réfléchir de savoir ce qu'il y a dedans)

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par boboss123 Voir le message
    => un char et un UINT8, ce n'est pas la même chose ?
    Ben je sais pas trop. Le char c'est le type natif. Le uint8 c'est un truc créé artificiellement. Il est probable que uint8 correspond à char mais je sais pas si c'est fait pour gérer du char.

    Citation Envoyé par boboss123 Voir le message
    oups effectivement ce n'est pas bon... je ne vois pas trop comment faire alors (je voudrais pouvoir balancer les valeurs de ma structure sans a voir à réfléchir de savoir ce qu'il y a dedans)
    Ben faut remplacer
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    strcpy(toto.name, "toto")
    Et idem pour toto.str...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    ça serait bon si cette chaine était stockée en RAM mais ce n'est pas le cas (stockée en ROM)

  8. #8
    Membre du Club
    Inscrit en
    Avril 2010
    Messages
    105
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 105
    Points : 63
    Points
    63
    Par défaut
    salut !

    Pour pouvoir avoir une chaine dynamique, il y a deux solutions :

    1 - soit tu déclare ton char* sans initialiser tout de suite, mais le truc c'est que pour changer par une chaine plus grande, ca risque de pas forcément être facile (pas trop dur non plus, il te faudra une chaine temporaire très grande et tu voit la taille de la nouvelle chaine en recherchant le '\0')

    2 - Tu mets en place une liste chaînée avec un booléen indiquant si oui ou non la chaine est fini (de cette manière, tu ne prends que la taille qui t' intéresse)

    la deuxième solution pouvant demander un peu plus de ressources mais étant plus facile à utiliser et réellement dynamique


    Pour le reste, j'ai pas trop regardé =)

    cdlt,

    naga

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    ok, merci

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

Discussions similaires

  1. [Débutant] Initialisation d'une structure
    Par Mat32 dans le forum MATLAB
    Réponses: 3
    Dernier message: 21/09/2010, 21h58
  2. initialisation d'une structure
    Par num09 dans le forum Débuter
    Réponses: 3
    Dernier message: 31/10/2008, 00h30
  3. initialisation d une structure
    Par rsouissi dans le forum C++
    Réponses: 1
    Dernier message: 21/04/2008, 13h46
  4. initialisation d'une structure
    Par ryadh.naouar dans le forum C
    Réponses: 3
    Dernier message: 29/10/2007, 15h21
  5. [Initialisation] Remplir une structure une fois
    Par Kimael dans le forum Langage
    Réponses: 14
    Dernier message: 08/06/2004, 15h33

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