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 :

Changement de variable incompréhensible


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Février 2009
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations forums :
    Inscription : Février 2009
    Messages : 25
    Par défaut Changement de variable incompréhensible
    Bonsoir tous le monde,

    Voilà je viens de tomber sur un problème incompréhensible...

    En gros l'IDE (Netbeans dans la vidéo, mais ca le fait aussi avec Code::Blocks et Dev C++) change mes valeurs de variables a la sortie d'une fonction void et je ne comprend pas du tout pourquoi.

    Ci dessous mes sources et une petite vidéo de démo.

    VIDEO -> ICI (Assez lourde : 26Mo mieux vaut la DL)

    main.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
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    /* 
     * File:   main.c
     * Author: Augustin
     *
     * Created on 4 novembre 2009, 22:29
     */
     
    #include "../../../../MinGW/include/stdio.h"
    #include "../../../../MinGW/include/stdlib.h"
    #include "struct.h"
     
    /*
     * 
     */
    int main(int argc, char** argv)
    {
        int nbeleves=0, nbelevesTemp=0;
        int *pnbeleves = &nbeleves;
        printf ("Combien d'eleves y a t-il?\n");
        scanf ("%d", &nbeleves);
        nbelevesTemp = nbeleves;
        e T[nbeleves-1];
        RemplirTab (T, nbeleves);
        nbeleves = nbelevesTemp;
        AfficherTab (T, nbeleves);
        return (EXIT_SUCCESS);
    }
    fonctioneleve.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
    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
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    #include "struct.h"
    #include "../../../../MinGW/include/stdio.h"
    #include "../../../../MinGW/include/stdlib.h"
     
    void RemplirTab (e T[], int nbeleves)
    {
        int i;
        i=0;
        while ( i < nbeleves)
        {
            printf ("Tapez un nom\n");
            scanf ("%s", &T[i].Nom);
            printf ("Quel est son prenom?\n");
            scanf ("%s", &T[i].Prenom);
            printf ("Quel est son numéro de securite sociale?\n");
            scanf("%ld", &T[i].Num);
            T[i].moyenne=-1; //initialisation de la moyenne a -1 pour faire au moins une fois le while
            while(T[i].moyenne > 20 || T[i].moyenne < 0)
            {
                printf ("Quelle est sa moyenne?\n");
                scanf ("%f", &T[i].moyenne);
                if(T[i].moyenne > 20 || T[i].moyenne < 0)
                    printf("ERREUR\nVous devez saisir une note entre 0 et 20\n");
            }
            i++;
        }
    }
     
    void AfficherTab (e T[], int nbeleves)
     {
         int i=0;
         while (i!= nbeleves)
         {
             printf ("%s %s : num securite sociale %ld, moyenne %.2f\n", T[i].Nom,T[i].Prenom,T[i].Num,T[i].moyenne);
             i++;
         }
     }
     
     
    /*void TrierTab (e T[], int nbeleves)
    {
        int i, cpt;
        e vl={"","",0,0};
        for (cpt=0; cpt<nbeleves;cpt++)
        {
            for (i=0;i<nbeleves;i++)
            {
                if (strcmp(T[i].Nom,T[i+1].Nom)>0)
                {
                    vl=T[i];
                    T[i]=T[i+1];
                    T[i+1]=vl;
                }
            }
        }
    }
     
    int ChercherVal (e T[], int nbeleves)
    {
        int i, eleve, trouve;
        printf ("quel est el numero de securite sociale de l'eleve?\n");
        scanf("%ld",&eleve);
        i=0;
        trouve=0;
        while (i<nbeleves && trouve==0)
        {
            if (T[i].Num==eleve)
            trouve= 1;
        }
        if(trouve==0)
        {
            i=-1;
            printf ("cet eleve n'est pas dans la liste\n");
        }
        else
            printf ("eleve trouve:\n%s %s : num securite sociale %ld, moyenne %.2f\n", T[i].Nom,T[i].Prenom,T[i].Num,T[i].moyenne);
        return i;
    }
     
    void SuprVal (e T[], int* pnbeleves)
    {
        int trouve,i, pos;
        pos=ChercherVal (T,&pnbeleves);
        if (pos!=-1)
        {
            for(i=pos;i<&pnbeleves;i++)
            {
                T[i]=T[i+1];
            }
            *pnbeleves=*pnbeleves-1;
        }
    }*/
    struct.h
    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
    /* 
     * File:   struct.h
     * Author: Augustin
     *
     * Created on 4 novembre 2009, 22:32
     */
     
    #ifndef _STRUCT_H
    #define	_STRUCT_H
     
    #define MAX_NOM 20
     
    typedef struct e
    {
        char Nom[MAX_NOM];
        char Prenom[MAX_NOM];
        long int Num;
        float moyenne;
    }e;
     
     
    void RemplirTab (e T[], int nbeleves);
    void AfficherTab (e T[],int nbeleves);
    void TrierTab (e T[], int nbeleves);
    int ChercherVal (e T[], int nbeleves);
    void SuprVal (e T[], int* nbeleves);
     
    #endif	/* _STRUCT_H */

  2. #2
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut
    T est un tableau, et donc quand tu fais 'RemplirTab (T, nbeleves);' tu envoies l'adresse de ton tableau.

    Ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void AfficherTab (e T[], int nbeleves)
    Est équivalent à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void AfficherTab (e *T, int nbeleves)
    Car le compilateur 'transforme' le [] en *.

    Donc en clair, tu envoies un pointeur à ta fonction, donc c'est normal que tu modifies les valeurs

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    En effet, à moins d'être dans une structure passée elle-même par valeur, un tableau n'est jamais passé par valeur à une fonction. C'est trompeur, mais je crois que c'est un reliquat des langages ancêtres du C.
    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
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Sa remarque ne porte pas sur le contenu du tableau, évidemment qu'il sera modifié et le posteur le sait puisqu'il le passe à une fonction pour qu'elle le remplisse.

    L'erreur est ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        e T[nbeleves-1];
        RemplirTab (T, nbeleves);
    le tableau fait nbeleves-1 éléments et on dit à la fonction qu'il fait nbeleves éléments.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void RemplirTab (e T[], int nbeleves)
    {
    ....
        while ( i < nbeleves)
        {
            printf ("Tapez un nom\n");
            scanf ("%s", &T[i].Nom);
    ....
    Du coup, celle-ci écrit en dehors du tableau va écraser la valeur d'autres variables.

    Accessoirement, on devrait avoir (T[i].Nom est un tableau)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            scanf ("%s", T[i].Nom);
    PS : Faire une vidéo ne remplace pas une explication claire du problème : tu aurais dû plutôt préciser quelles variables sont modifiées, après quelle fonction,...

  5. #5
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par 2rock Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #include "../../../../MinGW/include/stdio.h"
    #include "../../../../MinGW/include/stdlib.h"
    [HS] Pour éviter de telles inclusion, ton compilateur (ici: gcc) possède l'option -I. Normalement, ton compilateur gère ça de manière transparente pour ce qui concerhne la bibliothèque standard[/HS]

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

Discussions similaires

  1. Changement de variable de session onClick
    Par milach dans le forum Langage
    Réponses: 2
    Dernier message: 27/08/2007, 16h04
  2. Traduction d'un outil (changement de variable)
    Par new-dmx dans le forum Langage
    Réponses: 9
    Dernier message: 12/07/2007, 09h54
  3. Réponses: 20
    Dernier message: 12/06/2007, 10h11
  4. [VBA-E]Comment lancer une procedure lors d'un changement de variable ?
    Par RogerLapin dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 29/03/2007, 09h56
  5. Changement de variable
    Par Pchiter dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 23/08/2005, 14h26

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