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 :

structure dans une fonction


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    100
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations forums :
    Inscription : Décembre 2006
    Messages : 100
    Par défaut structure dans une fonction
    Bonsoir,

    Je suis nouveau et c'est mon premier post. Je tien a preciser que je suis debutant, je suis donc desolé si mon probleme vous parait ridicule

    donc voila: j ai ecris un petit programme en C pour m exercer.
    Dans ce programme j'ai une structure personne, avec plusieurs informations (par ex: le nom de la personne).J'ai fait un tableau de structure "tabpers", car il y a plusieurs "personnes".Ensuite j'ai ecris une fonction "aaa" ou la structure est passée par adresse avec un pointeur, jusque la tout va bien....

    Cette fonction doit m'afficher a l'aide d'une boucle les noms de ttes les personnes. le probleme est que je n'arrive pas a avoir acces au different niveau de tabpers.

    Je vous met le prog car il n est pas tres long :

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
     
    //prtotype de la fonction aaa
    void aaa(struct personne *point);
     
    //declaration de la structure en global et initialisation,
    struct personne
    	{
    	 char identite[15];
    	 char fonction[15] ;
    	 int anciennete;
    	 char tel[3];
    	 int present;
    	} tabpers[4]={{"a","aa",1,"aaa",1},
    			    {"b","bb",1,"bbb",1},
    			    {"c","cc",1,"ccc",1},
    			    {"d","dd",1,"ddd",1} };
     
     
    int main()
    {
    	//declaration puis initianisation du pointeur
    	personne *point=NULL;
    	point=tabpers;
     
    	 //appel de la fonction
    	 aaa(point);
     
    	 getch();
    	 return(0);
    }
     
    //definition de ma fonction aaa
    void aaa(personne *point)
    {
     int i;
     for(i=0;i<4;i++)
    	{
    	 printf("%s\n", (*point+i).identite); //c'est sur cette ligne que 
                                                          //pointe le compilateur : 
                                //"illegal structure operation in fonction aaa(personne)"
    	}
    }
    voila la bete lol.
    j ai reussi l operation avec un simple tableau d entier, mais pas avc cette structure.

    voila merci pour votre aide je vous aime

  2. #2
    Membre Expert
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Par défaut
    Ouh la...

    Bon, pour commencer, même si ceci n'est pas la source de l'erreur : déclare ta structure avant le prototype de la fonction aaa, c'est plus propre et plus lisible ainsi.

    Ensuite, déclare ton tableau à part, et pas en même temps que le type (d'ailleurs, je ne sais même pas pourquoi ça compile). Je dis bien "déclare" et non "définis". Comme ça par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    struct personne { /* declaration des champs de la structure */ };
     
    struct personne tabpers[4];
    Puis, dans le programme principal, initialise ton tableau correctement, comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    for(i = 0; i < 4; i ++)
    {
        (tabpers[i]).identite = /* ce qu'il faut */;
     
        /* etc... */
    }
    De plus, je pense que c'est une mauvaise idée de déclarer tes champs comme des tableau de caractères : il serait plus facile pour toi de les déclarer en tant que char *... le type des chaînes de caractères en C !

    Il y a aussi une autre chose : dans ta fonction aaa, il faut déclarer l'argument comme struct personne et non comme personne ; utilise également la notation tableau pour accéder aux éléments de ton tableau, c'est plus lisible et plus propre.

  3. #3
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    100
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations forums :
    Inscription : Décembre 2006
    Messages : 100
    Par défaut
    ok merci pour ton aide
    j ai modifé le code comme tu m a dis.
    en ce qui concerne la fonction, je l ai changée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void aaa(struct personne *point)
    {
     int i;
     for(i=0;i<10;i++)
    	{
    	 printf("%s\n", (*point[i]).identite);
    	}
    }
    j obtiens toujours la meme erreur que precedemment. A la base j avais
    deja utilisé la notion standard pour les tableau "tab[i]" mais sa n avais
    pas fonctionné , alors j ai essayé sa : *tab+i et la sa a marché, mais seulement pour un tableau a une dimension ; pas pr ma structure.

    est ce que qq1 d autre a une idée????

  4. #4
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    100
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations forums :
    Inscription : Décembre 2006
    Messages : 100
    Par défaut
    meci thewho
    j ai aussi modifié pour le champ tel, j ai mis tel[4]
    et j ai essayé sa pour ma fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    void aaa(struct personne *point)
    {
     int i;
     for(i=0;i<4;i++)
    	{
    	 printf("%s\n", (point+i).identite);
    	}
    }
    et cette fois si le compilateur me dit "structure required on left side of . or .* in function aaa(personne *)
    C est a n y rien comprendre!!!

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    633
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 633
    Par défaut
    Bonjour,

    Dans la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	 printf("%s\n", (*point+i).identite);
    pourquoi déréférencer le pointeur, c'est avec lui que tu veux faire un calcul, pas avec ce qu'il pointe.
    Il faut écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	 printf("%s\n", (point+i).identite);
    D'autre part, dans ta structure, tu as
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ...
    	 char tel[3];
    ...
    champ que tu initialises avec des choses comme "aaa", donc contenant 3 caractères, ce qui nécessite de réserver 4 caractères (ne jamais oublier le zéro final pour les chaînes).

    Normalement, ton compilateur aurait dû te signaler le problème (le mien le fait, mingw avec WinXP)

    De plus, je suis d'accord avec les remarques de InOCamlWeTrust, sauf
    Citation Envoyé par InOCamlWeTrust
    De plus, je pense que c'est une mauvaise idée de déclarer tes champs comme des tableau de caractères : il serait plus facile pour toi de les déclarer en tant que char *... le type des chaînes de caractères en C !
    C'est la même chose.

  6. #6
    Membre Expert
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Par défaut
    Citation Envoyé par thewho
    Bonjour,

    Dans la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	 printf("%s\n", (*point+i).identite);
    pourquoi déréférencer le pointeur, c'est avec lui que tu veux faire un calcul, pas avec ce qu'il pointe.
    Il faut écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	 printf("%s\n", (point+i).identite);
    Non : son code est juste. C'est le tient qui ne marche pas : point est un pointeur vers une structure, donc lui appliquer l'opérateur "." n'a aucun sens ici.

    Citation Envoyé par thewho
    D'autre part, dans ta structure, tu as
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ...
    	 char tel[3];
    ...
    champ que tu initialises avec des choses comme "aaa", donc contenant 3 caractères, ce qui nécessite de réserver 4 caractères (ne jamais oublier le zéro final pour les chaînes).

    Normalement, ton compilateur aurait dû te signaler le problème (le mien le fait, mingw avec WinXP)

    De plus, je suis d'accord avec les remarques de InOCamlWeTrust, sauf

    C'est la même chose.
    Et non ! Rien à voir, ce n'est absolument pas la même chose.

    Ecrire ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    struct personne { char identite[4]};
    n'est absolument pas équivalent à écrire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    struct personne { char *identite };
    Dans un cas tu as un champ de largeur 4 char, dans l'autre tu as un champ qui est un pointeur vers un vecteur de caractères... rien à voir !

    Pour le problème, c'est ça ce qu'il faut écrire, si identite est bien un char *

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void aaa(struct personne *point)
    {
     int i;
     for(i=0;i<10;i++)
            {
             printf("%s\n", (point[i]).identite);
            }
    }
    mais je préfère :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void aaa(struct personne point[10])
    {
     int i;
     for(i=0;i<10;i++)
            {
             printf("%s\n", (point[i]).identite);
            }
    }

  7. #7
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    100
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations forums :
    Inscription : Décembre 2006
    Messages : 100
    Par défaut
    nan c est tjr pareil InOCamlWeTrust.
    j ai changé la declaration des champ en char comme tu l a montré, avec char*.
    et j ai copié la fonction que tu a ecris mais sa me fait tjr la meme erreur (illegal structure operation...).
    est ce que sa ne serai pas un probleme de compilateur?

  8. #8
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    100
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations forums :
    Inscription : Décembre 2006
    Messages : 100
    Par défaut
    non ca y est!!!! c est rentré dans l ordre j ai fait exactement comme InOCamlWeTrust m'a dit et le prog marche!!!!! youpi

    j ai pas vraiment compri le mecanisme mais sa marche c est l essentiel!
    Pourquoi doit t on mettre point[i].blabla o lieu de *point[i].blabla?
    normalement il faut mettre "*" pour avoir la valeur de ce que pointe le pointeur non?

  9. #9
    Membre Expert
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Par défaut
    En C, on peut voir tout pointeur comme un tableau... mais l'inverse est FAUX.

    Ecrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct personne *point;
     
    /* du code... */
     
    (*(point + i)).identite = "aaa";
    ou écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct personne *point;
     
    /* du code... */
     
    (point[i]).identite = "aaa";
    c'est la même chose. En fait, écrire *(pointeur + deplacement) revient à coder pointeur[deplacement].

  10. #10
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par isma92
    Pourquoi doit t on mettre point[i].blabla o lieu de *point[i].blabla?
    normalement il faut mettre "*" pour avoir la valeur de ce que pointe le pointeur non?
    Malgré les apparence, le paramètre est un pointeur. Mais il se trouve qu'en C, grâces aux propriétés de l'arithmétique des pointeurs, la notation 'tableau' peut être utilisée avec les pointeurs.

    Si une fonction a pour paramètre int *a
    et que a contient l'adresse du premier élément d'un tableau de 4 int,
    on peut écrire dans la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void (int *a)
    {
       a[0] = 123;
       a[3] = 456;
    }
    Pareil si c'est un tableau de structure.

    Quand un problème parait compliqué, essayer de le traiter de manière simple...

    Ne pas considérer qu'il est résolu tant que tu ne peux pas expliquer ce qui se passe de A à Z. on ne programme pas au hasard.

  11. #11
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    633
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 633
    Par défaut
    Bonjour,
    @InOCamlWeTrust

    Tu as en partie raison, mon code n'est pas bon parce que j'ai fait une erreur de copier/coller, il fallait lire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	 printf("%s\n", (point+i)->identite);
    Et plus loin, quand j'affirme "c'est la même chose", cela signifie :
    Qu'on déclare un tableau de longueur définie, ou un pointeur (qu'il faut initialiser), dans tous les cas, on a affaire à une chaine de caractères.

    Et mettre, comme tu le proposes, des pointeurs dans la structure, change énormément l'utilisation de la structure, en particulier pour la copier : il faut penser à réserver la place nécessaire pour chaque donnée correspondant à un pointeur, et copier les données correspondant, sinon la seule copie des pointeurs conduit à un comportement probablement non désiré : pour chaque copie, les pointeurs sont identiques, et par conséquent, la modification d'une donnée est répercutée dans toutes les variables ainsi copiées.
    Donc, travail supplémentaire non négligeable, qu'on évite en mettant des tableaux de longueur prédéterminée (bien entendu, cela n'est valable que si on connaît la longueur maximale que peuvent atteindre les données).

  12. #12
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par InOCamlWeTrust
    Ecrire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    struct personne { char identite[4]};
    n'est absolument pas équivalent à écrire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    struct personne { char *identite };
    Ben si.

    Tu confonds les tableaux et les pointeurs. Dans un paramètre de fonction, on a pas de tableaux, mais des pointeurs dont la notation peut ressembler à la syntaxe tableau. OK, c'est confusant, mais c'est comme ça.

    http://emmanuel-delahaye.developpez.....htm#param_tab

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

Discussions similaires

  1. probleme d'une structure dans une fonction
    Par saadaoui_1 dans le forum C++
    Réponses: 3
    Dernier message: 24/04/2014, 14h50
  2. Problème avec structure dans une fonction
    Par Saliman dans le forum C
    Réponses: 2
    Dernier message: 22/11/2007, 11h45
  3. Passage d'une structure dans une fonction
    Par god_enel dans le forum C
    Réponses: 7
    Dernier message: 01/02/2007, 15h33
  4. Passage d'une structure dans une fonction
    Par god_enel dans le forum C
    Réponses: 8
    Dernier message: 22/01/2007, 15h35
  5. Passer une structure dans une fonction ...
    Par pilouface dans le forum C
    Réponses: 4
    Dernier message: 03/04/2006, 01h00

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