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éfinition de structure dans le main


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 47
    Par défaut définition de structure dans le main
    Bonsoir, j'explique mon problème :

    j'ai définit une table de voiture comme cela:

    typedef struct { float prix; Nat imm; .... } svoiture, *voiture

    typedef voiture table_voiture[100];

    dans le main() je veux déclarer une table de voiture et l'initialiser à vide:

    table_voiture *t1=MALLOC(table_voiture);
    t1=tablenouv(); où tablenouv() initialise la table à vide.

    jusque la tout est ok.

    mais seulement j'ai une fonction (en dehors du main()) qui doit utiliser cette table. Or mon compilateur m'indique que la table t1 n'est pas déclaré, et qu'il faut que je la déclare, ce que je vais. Puis nouvelle erreur, il faut l'initialiser à vide sinon gros bug dans mon programme. Hélas la dite fonction est appelée plusieurs fois et cela a pour effet de re vider le tableau à chaque fois que la fonction est appelée, ce qui ne m'arrange pas puisque la table de voiture doit être mise a jour avec la nouvelle quantité de voitures en stock lors d'un achat..

    Quelqu'un a une idée pour déclarer cette table dans le main() et que je puisse l'utiliser dans d'autres fonctions sans la re déclarer ?

    Merci d'avance pour votre aide !

  2. #2
    Membre averti
    Inscrit en
    Décembre 2009
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 22
    Par défaut
    Quand tu fais ton malloc n'oublie pas de caster le résultat: si tu regardes le prototype de malloc tu peux te rendre compte qu'il renvoie un void*

    une possible amélioration serait donc:

    table_voiture* t1= (table_voiture*)malloc(sizeof(table_voiture));

    Ensuite, si tu pouvais montrer ton code ca serait plus pratique pour t'aider =)

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 47
    Par défaut
    Merci de bien vouloir m'aider

    voila a quoi ressemble mon code :

    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
     
    void main(void)
     
    {
    table_voiture *t1=MALLOC(table_voiture); /* ps: j'ai un #define MALLOC(t) ((t *)(malloc(sizeof(t))))*/
     
    t1=tabnouv();
    Voiture a;
    a.categorie="BMW"; /*categorie etant une chaine */
    a.prix=1300;
    a.quantite=100;
    t1=adjt(*t1,1,a) /* j'appel adjonction qui prend une tablevoiture , un indice et une voiture et qui rempli le champ si l'indice n'est pas deja utilisé par une autre voiture */
    .
    .
    .
    }
    ensuite pour le menu j'ai une fonction traite choix:


    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
    Bool traite_choix2(char c)
    {
    	if(c=='q') return Faux;
    	switch(c)
    	{
    	case 'a' :
    		do
    		{	
    		print_menu_BMW();
    		} while(traite_choix_BMW(getch()));
    		break;
     
    	default : printf("\ ----> commande non reconnue\n");
    	}
    	return Vrai; 
    }
     
     
     
    Bool traite_choix_BMW(char c)
    {
    	if(c=='q') return Faux;
    	switch(c)
    	{
    	default : printf("\ ----> commande non reconnue\n");
    	}
    	return Vrai;
    }
     
    void print_menu_BMW(void)
    {
    Nat i;
    /* c'est ici que je suis censé declarer ma table et l'initialiser */
    	for (i=0;i<100;i++)
    	{
    		if (t1[i]->categorie=="BMW")
    		{
    		printf(" ref : %d ,produit: %s prix : %f , quantite en stock: %f \n",i,t1[i]->nom,t1[i]->prix,t1[i]->quantite);
    		}
    	}
     
    	puts("\n  q  : quitter");
    }
    Mon problème est donc que si dans print_menu_BMW() j'initialise ma table de voiture, alors à chaque fois que je vais quitter le menu puis revenir dans ce même menu, j'aurai à chaque fois une nouvelle table..

  4. #4
    Membre averti
    Inscrit en
    Décembre 2009
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 22
    Par défaut
    ben en fait c'est normal, quand tu appelles ta fonction print_menu, elle ne connait jamais le tableau t1, il faudrait que tu le transmette par argument afin de modifier le pointeur... en gros dans ce que tu fais, ( je comprend pas qu'il n'y ait pas d'erreur ou de warning a la compilation d'ailleurs )
    c'est que tu fais un test avec quelque chose qui n'existe pas =)

    si j'ai bien compris ton problème est que ton programme ne se remémore pas être déjà passé par la fonction ?

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 47
    Par défaut
    j'ai essayer de passer la table de voiture t1 en parametre de la fonction printmenu, mais le compilateur me donne comme erreur "t1 is used without being initialised", en gros je dois obligatoirement lui donner l'instruction t1=tablenouv() pour compiler ...

  6. #6
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par astyan42 Voir le message
    Quand tu fais ton malloc n'oublie pas de caster le résultat: si tu regardes le prototype de malloc tu peux te rendre compte qu'il renvoie un void*
    Ce cast n'est pas obligatoire (et même assez décrié). Il y a en C conversion implicite de void* vers n'importe quel type de pointeur.

    Citation Envoyé par gbsatti Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void main(void)
     
    {
    table_voiture *t1=MALLOC(table_voiture); /* ps: j'ai un #define MALLOC(t) ((t *)(malloc(sizeof(t))))*/
     
    t1=tabnouv();
    Sans aller plus loin, deux remarques :
    • Les prototypes normalisés de main() sont int main(void) et int main(int argc, char* argv[]), pas void main(void).
    • Le retour de tabnouv() écrase l'adresse obtenue du malloc(). Au mieux tu as une fuite mémoire (n'ayant plus le pointeur, tu ne peux plus libérer cette mémoire) et au pire tu as corruption mémoire.

    Sinon, plutôt que de poster un bout ou deux de code, peux tu fournir un exemple minimal mais compilable mettant en évidence le problème. Parce que là, à part faire des suppositions sur le code qui manque, difficile d'aider.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 47
    Par défaut
    je ne peux pas poster mon code ici par peur d’être plagié (on est quand même toute une classe hein..)

    mais mon problème est simple, je cherche juste à déclarer une table de voiture t1 "une fois pour toute" afin de pouvoir appeler t1 un peu partout dans mon programme sans avoir à la re déclarer à chaque fois...

    merci d'avoir essayé en tout cas

    bonne nuit

  8. #8
    Membre averti
    Inscrit en
    Décembre 2009
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 22
    Par défaut
    oui, c'est ce qu'on essaie de t'expliquer, qu'il y a un problème lors de la déclaration de ton pointeur en fait.
    Ensuite, soit tu fais transiter ton pointeur par argument dans tes fonctions et tu n'a plus qu'a agir sur ce pointeur
    Ou autre solution, souvent déconseillée, déclarer ton t1 en tant que variable globale.
    a la rigueur si tu as peur d'être plagié envoie moi un mp avec le code de ton initialisation, je pourrais peut-être te filer un coup de main =)

  9. #9
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 836
    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 836
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par gl Voir le message
    • Les prototypes normalisés de main() sont int main(void) et int main(int argc, char* argv[]), pas void main(void).
    On a aussi int main(int argc, char *argv[], char *envp[]) si on doit récupérer son environnement de travail...

    Citation Envoyé par gbsatti Voir le message
    table_voiture *t1=MALLOC(table_voiture);
    t1=tablenouv(); où tablenouv() initialise la table à vide.

    jusque la tout est ok.
    Non. Là déjà ça foire. C'est comme si tu écrivais i=5 puis i=0 en disant "ok, j'ai maintenant i qui vaut 5"

    Une fonction qui initialise un contenant doit recevoir l'adresse de ce contenant
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    table_voiture *t1=malloc(sizeof(table_voiture));  //le cast est en effet plus qu'inutile, il peut masquer un oubli de prototypage
    tablenouv(t1);
     
    void tablenouv(table_voiture *pt)
    {
         pt->...=...
         pt->...=...
        etc
    }

    Quand à ma remarque générale, si tu dois écrire un projet, essaye de normaliser tes trucs. Les types pourront être t_qqchose. Les structures pourront être struct s_qqchose. Les noms de variable pourront être en rapport avec leur utilité...

    Citation Envoyé par gbsatti Voir le message
    mais mon problème est simple, je cherche juste à déclarer une table de voiture t1 "une fois pour toute" afin de pouvoir appeler t1 un peu partout dans mon programme sans avoir à la re déclarer à chaque fois...
    Variable globale. La pire des solutions. Si ton prof est un programmeur qui aime ce métier, il ne va pas du tout apprécier. C'est quand-même pas la mort d'embarquer un pointeur dans une fonction quoi !!!

    Citation Envoyé par gbsatti Voir le message
    j'ai définit une table de voiture comme cela:

    typedef struct { float prix; Nat imm; .... } svoiture, *voiture

    typedef voiture table_voiture[100];
    Ouh là, plus je lis ton truc plus je remonte des horreurs. Là c'est le meilleur moyen pour te planter. Tu masques les étoiles, tu masques les tableaux. Donc déjà le malloc de tout à l'heure était totalement inutile vu que la taille est fixée à 100. Et dans 10 jours quand tu utiliseras table_voiture, tu ne sauras plus de quoi il est question. Et ton prof, quand il devra te relire...

    Tu peux pas rester simple ???
    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
    typedef struct {
         float prix;
         char immat[9];
         ...
    } t_voiture;
     
    # define NB_VOITURE 100
     
    int main()
    {
         t_voiture tableau_voiture[NB_VOITURE];  // Comme ça plus de malloc d'une taille fixe ce qui est totalement crétin
         init_tableau_voiture(tableau_voiture);
    }
     
    void init_tableau_voiture (t_voiture *tab)
    {
         t_voiture *pt;
         int i;
         for (i=0, pt=tab; i < NB_VOITURE; i++, pt++)
         {
              pt->prix=0;
              pt->immat[0]=0;
              ...
         }
    }
    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]

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 47
    Par défaut
    Merci pour vos conseil.
    Pour ce qui est du MALLOC, c'est vrai que j'ai été naïf d'allouer de la memoire pour un tableau statique.

    J'ai résolu mon problème en embarquant le pointeur de la table dans chaque fonction qui l'utilise ! et j'ai tout déclaré dans le main !

    merci donc à Sve@r tes conseil m'ont été très utiles.

    bonne journée

  11. #11
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    <HS>

    Citation Envoyé par Sve@r Voir le message
    On a aussi int main(int argc, char *argv[], char *envp[]) si on doit récupérer son environnement de travail...
    Non, il est certes fréquent (enfin tant qu'on reste dans des environnements classiques) mais pas normalisé.

    La norme autorise une implémentation à fournir d'autres formes pour main(), comme celle-ci, par contre on perd en portabilité.

    </HS>

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

Discussions similaires

  1. declarer une structure dans le main
    Par kochfet dans le forum Langage
    Réponses: 8
    Dernier message: 21/09/2013, 20h01
  2. [MFC] Passage d'une structure dans une method
    Par KPitN dans le forum MFC
    Réponses: 5
    Dernier message: 18/06/2004, 10h11
  3. Réponses: 5
    Dernier message: 25/04/2004, 00h57
  4. Problème de rangement de structure dans un fichier ...
    Par Freeze dans le forum C++Builder
    Réponses: 8
    Dernier message: 16/12/2003, 16h46

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