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 :

Question sur les structures en langage C


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2017
    Messages : 10
    Points : 13
    Points
    13
    Par défaut Question sur les structures en langage C
    Bonsoir ,
    Alors voila je suis etudiant en faculté et j'ai quelques questions a propos des structure en language C
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    	typedef struct Date_de_naissance {
    		int jour;
    		int mois;
    		int anne;
    	} Date;
     
    	typedef struct Etudiant{
    		int matricule;
    		char nom[21];
    		char prenom[21];
    		Date date_de_naissance;
    		float moyg;
    	} Etudiant;
    Alors voila j'ai définit une structure qui s’appelle étudiant avec les champs suivant et je dois crée une fonction saisie_etudiant qui nous saisie les information de l’étudiant et j'ai fais cela
    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
     
    void saisie_etudiant (Etudiant *e){
    	printf("Saisie des donnees de l'etudiants .. \n");
    	printf("Veuillez entrez la matricule de l'etudiant : ");
    	scanf("%d",&e->matricule);
    	printf("Veuillez entrez le nom de l'etudiant : ");
    	scanf("%s",e->nom);
    	printf("Veuillez entrez le prenom de l'etudiant : ");
    	scanf("%s",e->prenom);
    	printf("Veuillez entrez la datte de naissance de l'etudiant : ");
    	scanf("%d %d %d",&e->date_de_naissance.jour,&e->date_de_naissance.mois,
    	&e->date_de_naissance.anne);
    	printf("Veuillez entrez la moyenne generale de l'etudiant : ");
    	scanf("%d",e->moyg;
    }
    alors mes questions son les suivantes :
    1. Est ce que les structure marche comme un tableau ? je veut dire est ce que ecrire &e au lieu de &e->matricule est equivalent (le pointeur pointe sur la premiére case ?)
    2. Ma deuxieme question est pourquoi quand j'ecris &e->date_de_naissance->anne ca ne marche pas ? quand dois je utiliser -> ou le point ?


    Merci d'avance pour vos réponse.

  2. #2
    Nouveau membre du Club Avatar de ethan007
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Mars 2015
    Messages : 20
    Points : 31
    Points
    31
    Par défaut
    Bonjour, bienvenue,

    Déja je me demande si tu a exécuté ce code pour voir le résultat, tu aurais constaté que ta fonction de saisie à un petit problème:
    • tu à oublié la parenthèse pour la moyenne...
    • bug sur la moyenne car tu aurais dû passer l'adresse du champs moyenne. (il suffit de se rappeler que la fonction scanf prend toujours l'adresse de la variable)


    Petite astuce: il faut prendre l'habitude de rajouter un espace lorsque tu fais plusieurs scanf de suite afin d'éviter la copie du caractère \n (touche entrée) dans ton buffer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
           int code = 0;
           printf("Entrez le code à 4 chiffres \n");
           scanf(" %d", &code);
          //      ^
         //attention, un seul espace!!
    Citation Envoyé par CouscouS1337 Voir le message
    Tu affiches la moyenne (de type float) avec un %d...ok j'aimerais bien qu'on arrondisse ma moyenne par excès et non par défaut^^

    Citation Envoyé par CouscouS1337 Voir le message
    alors mes questions son les suivantes :
    1. Est ce que les structure marche comme un tableau ? je veut dire est ce que écrire &e au lieu de &e->matricule est équivalent (le pointeur pointe sur la première case ?)
    OUI l'adresse de la structure est aussi l'adresse du premier champ de la structure ! MAIS les structures ne se manipulent pas comme des tableaux..
    EX:
    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
     
        char  nom[10];
        printf("L'adresse du tableau est: %p et l'adresse de la première case est (aussi) %p\n", &nom, &nom[0]);
        //Affiche toujours la même adresse pour les deux
     
         typedef struct t_point{
            float x;
            float y;
         }t_point;
        t_point pointA;
        pointA.x = 2;
        pointA.y = 13.5;
        printf("L'adresse de (toute) la structure est: %p et l'adresse du premier champ est  aussi %p\n", &pointA, &(pointA.x));
        //Affiche toujours la même adresse pour les deux

    MAIS... c'est impossible de manipuler la structure comme on le ferais sur un tableau, en réalité rien ne garanti que les champs de la structure seront toujours contiguës, chaque champs peut être dispersé de part et d'autre dans la mémoire! néanmoins certains compilateurs allouent des blocs consécutifs pour les structures petites (2 champs int par exemple).
    EX: ceci est incorrect:
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
       pointA[0] = 12.5;  // Car la structure ne fonctionne pas
       pointA[1] = 0.5;  //comme un tableau

    Citation Envoyé par CouscouS1337 Voir le message
    Ma deuxième question est pourquoi quand j’écris &e->date_de_naissance->anne ça ne marche pas ? quand dois je utiliser -> ou le point ?
    Dans ton cas tu ne peux pas écrire &e->date_de_naissance->anne parce que date_de_naissance n'est pas on pointeur! tu aurais pu faire cela si tu réussi à avoir l'adresse du champ date_de_naissance comme suit:
    EX:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int  mettre_a_jour_annee(Etudiant *etudiant){
         printf("Entrez la nouvelle annee\n");
         scanf(" %d",&(&etudiant->k)->anne);
        /*ceci fonctionne car on a réussi à avoir l' adresse de la case date_de_naissance à elle toute seule 
        en suite comme c'est une adresse il faut faire flêche pour accèder au champ annee,
        ensuite l'adresse d'année on la passe on la passe à scanf()..
       NB: faire attention aux parenthèses
       */
    }
    Pour faire simple: avant d'utiliser la flèche sur une structure (ou un champ) se poser la question: <<Est ce que la structure que je manipule est actuellement pointeur /adresse ?>> si oui alors la flèche si ce n'est ni un pointeur ni une adresse alors on utilise le point.
    J'espère avoir répondu a tes questions.
    A bientôt.

  3. #3
    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
    Bonjour
    Citation Envoyé par CouscouS1337 Voir le message
    Est ce que les structure marche comme un tableau ? je veut dire est ce que ecrire &e au lieu de &e->matricule est equivalent (le pointeur pointe sur la premiére case ?)
    Non. Même si les champs sont généralement accolés, rien ne le garantit (le compiateur peut rajouter des octets de remplissage pour optimiser). Donc tu veux t'adresser au champ "X", alors tu le nommes.
    En plus, ce ne serait pas évolutif. Si d'aventure "&e" correspondait à son premier champ "&e->matricule" MAIS que demain un champ vienne se rajouter devant, il te faudrait alors reprendre tout ton code pour remplacer "&e" par "&e->matricule".
    Et puis ce ne serait pas non plus super lisible.

    Donc non. Tu fais les choses bien, et tu nommes les champs auxquels tu t'adresses.

    Citation Envoyé par CouscouS1337 Voir le message
    Ma deuxieme question est pourquoi quand j'ecris &e->date_de_naissance->anne ca ne marche pas ? quand dois je utiliser -> ou le point ?
    Ahaha, la question qui tue !!!

    La vraie réponse est "dans l'absolu, si tu utilises toujours le point mais que tu l'utilises correctement alors pas de souci".

    Essayons avec un exemple tout con : une stucture qui contient une variable classique int et un pointeur
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef struct {
    	int nbr;
    	char *pt;
    } t_simple;

    Cette structure (qui est devenu un type), peut être attribué à une variable (t_simple var) et à un pointeur (t_simple *adr=&var)

    Si tu utilises la variable simple, alors c'est toujours "point" (printf("%d - %c\n", var.nbr, *var.pt)). C'est là qu'il ne faut pas se rater et se souvenir que l'étoile s'applique à "pt" et non "var".
    Et si tu veux les adresses de l'exemple précédent, tu rajoutes "&" en te souvenant que "&*" s'annulent => scanf("%d - %c\n", &var.nbr, var.pt).

    Si tu utilises le pointeur "adr", alors pour obtenir le même résultat il faut demander "le pointé de adr" autrement dit "*adr" et le reste sans changement. MAIS comme le point est plus prioritaire que l'étoile, il faut alors mettre "*adr" entre parenthèses => printf("%d - %c\n", (*adr).nbr, *(*adr).pt). Attention à la lecture car *(*adr).pt se lit en commençant par "*adr" (ce qui est pointé par adr) puis "jumper au membre pt" puis "récupérer le pointé de tout ça".

    Cette écriture à base de point fonctionne donc même avec un pointeur. Mais elle est lourde. C'est pour ça qu'a été créé l'opérateur flèche. Ainsi adr-> équivaut à (*adr).. Et c'est là qu'il ne faut pas non plus se rater et se souvenir que la flèche s'applique à l'élément placé avant lui (et non après). Ainsi adr->xxx signifie "adr est un pointeur", sans présumer de la nature de "xxx".
    Donc l'exemple précédent se réécrit plus simplement printf("%d - %c\n", adr->nbr, *adr->pt).
    Et si tu veux les adresses, alors rajouter "&" comme tout à l'heure => scanf("%d - %c\n", &adr->nbr, adr->pt).

    Donc pour ton &e->date_de_naissance->anne ça ne peut pas marcher car "date_de_naissance" n'est pas un pointeur => &(e->date_de_naissance.anne) (j'ai mis des parenthèses pour que tu comprennes bien qu'on parle ici de l'adresse de "anne" et non de l'adresse de "e" mais bien entendu elles ne sont pas nécessaires).

    Et pas besoin de donner un nom à ta structure si tu lui donnes un type surtout que ce nom est faux (ce n'est pas une structure dédiée à gérer une date de naissance mais une date tout court, et c'est l'utilisateur qui définira son rôle). Et si en plus tu prends le temps de bien réfléchir aux types nécesaires à ton algo, c'est du bénéfice pour le futur.
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct {
    	unsigned short jour;
    	unsigned short mois;
    	unsigned short anne;		// Je présume évidemment qu'on ne gèrera pas des personnes nées avant l'an 0 !!!
    } t_date;
    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]

  4. #4
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2017
    Messages : 10
    Points : 13
    Points
    13
    Par défaut
    Alors merci beaucoup pour vos réponse : Sve@r , ethan007. J'ai bien assimiler ce que vous m'avez expliqué ! Merci encore une fois pour votre réponse !

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

Discussions similaires

  1. Question sur les Structures
    Par Gueuz dans le forum Débuter
    Réponses: 2
    Dernier message: 15/05/2010, 17h23
  2. question sur les structures de données
    Par yacin87 dans le forum Débuter avec Java
    Réponses: 1
    Dernier message: 10/04/2010, 01h01
  3. Question sur les structures
    Par lassault1 dans le forum Débuter
    Réponses: 3
    Dernier message: 08/04/2010, 00h53
  4. Question sur les structures de données
    Par sliderman dans le forum Débuter
    Réponses: 8
    Dernier message: 16/07/2008, 20h40
  5. Petite question sur les structures
    Par progfou dans le forum C
    Réponses: 5
    Dernier message: 21/06/2006, 15h49

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