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 :

la sempiternelle erreur de débutant


Sujet :

C

  1. #1
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Mai 2013
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2013
    Messages : 12
    Points : 11
    Points
    11
    Par défaut la sempiternelle erreur de débutant
    Bonjour
    Je débute dans C et j'ai un bug. Je suis sûre que c'est un truc tout bête mais je relis mon code je n'arrive pas à identifier l'erreur
    Je crée un tableau, je demande de saisir d'abors la taille du tableau
    Puis je demande de rentrer les valeurs du tableau une à une, via une boucle
    Je compile, le programme me demande la valeur de la taille du tableau, je rentre une valeur et boucle infinie

    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
    17
    18
    19
    20
    #include <stdio.h>
     
    int main ()
    {
    	int n;
     
    	printf ("taille du tableau ?\n");
    	scanf("%d", &n);
    	int tableau [n] ;
     
    	for (int i =0; i <n; i++)
    		scanf("%d", &tableau[i]);
     
    	/*for (int i=0; i<n; i++)
    		printf("%3d", tableau[i]);*/
     
    	printf("\n");
     
    	return 0 ;
    }

  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 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par eowyn113 Voir le message
    Je suis sûre que c'est un truc tout bête mais je relis mon code je n'arrive pas à identifier l'erreur
    C'est parce qu'il n'y a aucune erreur

    Citation Envoyé par eowyn113 Voir le message
    Je compile, le programme me demande la valeur de la taille du tableau, je rentre une valeur et boucle infinie
    Non pas boucle infinie. Ton programme fait exactement ce que tu lui as demandé de faire à ce moment : attendre que tu saisisses les "n" valeurs de ton tableau. Ni plus, ni moins.
    Lui as-tu par exemple demandé d'afficher un petit message explicatif de l'action à effectuer ? Non. Donc il n'affiche rien et se contente que tu fasses ce que tu es sensée faire à ce moment => taper des valeurs.

    Remplace ta boucle par celle-ci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for (int i=0; i < n; i++) {
    	printf("Entrez la valeur tab[%d] :", i);
    	fflush(stdout);
    	scanf("%d", &tableau[i]);
    }
    Et décommente la suivante.
    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
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Ton programme pourtant grammaticalement correct reste à la merci d'une menaçante épée de Damoclès.

    Vois-tu le danger ?

  4. #4
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 291
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 291
    Points : 4 941
    Points
    4 941
    Billets dans le blog
    5
    Par défaut
    Allez, une petite piste .

    n appartient à quel ensemble ?

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Oh comme vous êtes méchants !!!
    C'est une débutante. Laissez-lui le plaisir de voir son code fonctionner avant de lui parler de ses dangers potentiels (parce que ça, quoi qu'il arrive, ça viendra toujours bien assez tôt)...

    PS: ceci dit, comme on ne l'a pas vue depuis hier 15h55 je pense qu'elle s'est désintéressée de ce topic probablement parce qu'elle a trouvé toute seule donc à mon avis, tout ce qu'on pourra dire dessus restera inutile
    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]

  6. #6
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Mai 2013
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2013
    Messages : 12
    Points : 11
    Points
    11
    Par défaut
    quel boulet je fais !

    Sve@r : merci !

    Matt_Houston :
    à la louche :
    -variables mal nommées ?
    - (déclarer à l'intérieur d'une boucle il faut indiquer une option spécifique au compilateur)
    Je n'ai pas tout le temps accès à internet, je peux pas répondre tout de suite
    Mais no problem, je ne vois aucune méchanceté dans les réponses, je suis juste une formation où on a peu de temps et du boulot d'où la tendance à aller vite

  7. #7
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 291
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 291
    Points : 4 941
    Points
    4 941
    Billets dans le blog
    5
    Par défaut
    Ha tu vois Sv@er, on n’est pas méchant

    Non eowin113 le problème ne vient pas des noms de tes variables.

    Imagine que l’utilisateur entre -2 par exemple pour la taille du tableau. Que va-t-il se passer ?

  8. #8
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Mai 2013
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Mai 2013
    Messages : 12
    Points : 11
    Points
    11
    Par défaut
    @gerald3d : oui, bonne question. Je suis des cours à la fac, là ils nous apprennent l'algorithmique le début tout ça.
    Ça peut sembler bête (?) mais on a déjà un programme chargé des profs qui n'ont pas l'air incompétents, je suis le rythme des profs et leurs exos.
    J'ai déjà galéré à savoir itérer

    Pour sortir du cadre scolaire et répondre à ta remarque, je suppose qu'il faudrait faire quelque chose du genre
    (au pif, parce que c'est sûrement pas au point)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    scanf("%d", &n);
    while (n<0)
    {
        printf("la valeur doit etre positive ou egale a zero");
        scanf("%d", &n);
    }
     
    	int tableau [n] ;
     
     
    	for (int i =0; i <n; i++)
    		scanf("%d", &tableau[i]);

  9. #9
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 291
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 291
    Points : 4 941
    Points
    4 941
    Billets dans le blog
    5
    Par défaut
    C’est un bon début.

    Ensuite il te faut vérifier si effectivement l’utilisateur a respecté la consigne.

    Un petit «*if*» après le scanf (); serait une bonne idée. Tu peux par exemple quitter ton programme avec un message spécifiant que la consigne n’a pas été respectée.

  10. #10
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par eowyn113 Voir le message
    Pour sortir du cadre scolaire et répondre à ta remarque, je suppose qu'il faudrait faire quelque chose du genre
    (au pif, parce que c'est sûrement pas au point)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    scanf("%d", &n);
    while (n<0)
    {
        printf("la valeur doit etre positive ou egale a zero");
        scanf("%d", &n);
    }
     
    	int tableau [n] ;
     
     
    	for (int i =0; i <n; i++)
    		scanf("%d", &tableau[i]);
    Alors déjà on va prendre de suite les bonnes habitudes : un programme ça s'indente correctement. On ne met pas 2 espaces dans la première boucle puis une tabulation dans la seconde etc. Sinon ton code va vite devenir illisible et un code illisible ben nous on ne le lit pas (s'il faut galérer 3h pour déterminer dans quelle boucle on se trouve à tel endroit du code...)

    Sinon le bon point c'est que t'as la bonne idée et le bon réflexe => faire saisir et répéter tant que ce n'est pas bon. Il te manque juste un peu d'expérience. Par exemple tu demandes deux scanf() pour la même saisie et ça c'est un peu dommage
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while (1) {
    	scanf("%d", &n);
    	if (n > 0) break;
    	printf("la taille du tableau doit etre positive !!!\n");
    }

    Sinon t'as aussi le droit de travailler en unsigned (je préconise d'ailleurs toujours aux gens de commencer par réfléchir avec attention au type de leurs variables qu'ils veulent utiliser
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main () {
    	unsigned short n;
     
    	printf ("taille du tableau (nombre positif uniquement) ?\n");
    	scanf("%hu", &n);
    	int tableau [n] ;
    	... 
    }
    Bon effectivement dans ce cas si le crétin qui utilise ton programme rentre "-1" ça lui fera 65535 mais bon faut aussi parfois savoir faire la part des choses et ne pas non plus tenter d'assumer toute la misère des utilisateurs incapables de se conformer aux consignes
    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]

  11. #11
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Citation Envoyé par eowyn113 Voir le message
    je suis juste une formation où on a peu de temps et du boulot d'où la tendance à aller vite
    Citation Envoyé par eowyn113 Voir le message
    e suis des cours à la fac, là ils nous apprennent l'algorithmique le début tout ça.
    Ça peut sembler bête (?) mais on a déjà un programme chargé des profs qui n'ont pas l'air incompétents, je suis le rythme des profs et leurs exos.
    J'ai déjà galéré à savoir itérer
    Cela va de soi et loin de moi l'idée de t'admonester. Nous sommes développeurs professionnels pour la plupart ici et connaissons les contraintes du monde réel. Nous aussi codons parfois () à l'arrache et ce n'est pas un mal en soi, mais il faut le faire en connaissance de cause.

    En écrivant ton programme tu as pris des décisions, qu'il faut justifier. Le C n'est pas un langage compliqué, le plus gros travail de formation que tu dois fournir en tant que programmeur/euse est d'apprendre à (re)connaître les conséquences des possibilités de conception qui s'offrent à toi, puis à choisir une implémentation adaptée.

    Si tu prends maintenant le temps de bien comprendre les choses, ce temps te sera plus tard rendu au centuple. Ou plutôt, tu n'en perdras plus.


    Citation Envoyé par eowyn113 Voir le message
    à la louche :
    -variables mal nommées ?
    Non : ton programme ne fait rien de particulier, occupe à peine une dizaine de lignes ; je pense qu'on peut faire l'économie de verbeuses précisions.


    Citation Envoyé par eowyn113 Voir le message
    - (déclarer à l'intérieur d'une boucle il faut indiquer une option spécifique au compilateur)
    Non plus : déclarer les variables - y compris les compteurs - en début de bloc n'est plus obligatoire (et même bad practice, IMHO) depuis la norme de 1999 et tu es sensée apprendre à coder en C11 (2011). On pourrait même arguer que tu as déclaré n trop tôt.


    L'épée de Damoclès que j'ai évoquée est autre et je vais généraliser la réponse de gerald3d. Tu as utilisé une construction C qui n'est pas anodine (bien qu'elle le paraisse) pour introduire un défaut bien plus dangereux et fondamental dans ton programme, au-delà du langage : tu acceptes une entrée utilisateur pour l'utiliser dans une opération critique, sans la valider. Je ne peux pas assez souligner ce point : ne fait jamais confiance à l'utilisateur.

    Voici la déclaration qui me tracasse, à première vue inoffensive : int tableau [n] ;. Cette ligne demande au compilateur d'instancier un variable-length array, dit VLA, une fonctionnalité d'ailleurs introduite par la norme C99. Ce type d'objet n'est pas un tableau au sens propre du terme, les tableaux ont une taille fixe et connue à la compilation. Il s'agit d'une sorte de wrapper autour de l'appel non-standard alloca qui fournit un buffer alloué sur la pile* dont la taille est connue à l'exécution. Contrairement** à une allocation sur le tas* via les appels de la famille de malloc, un échec d'allocation sur la pile est fatal soit au processus en cours, soit à l'intégrité du système, et n'est jamais détectable. D'autant plus que la taille de la pile est très limitée : elle se compte par défaut en mégaoctets sur une machine de bureau. Tu n'as sans doute pas compris la moitié de ce que je viens d'écrire ici, mais relis ce post lorsque tu auras terminé ton semestre de C.

    Bref : en demandant au compilateur de réserver un buffer de taille n, tu donnes donc les rênes à son utilisateur et tu ne peux absolument plus rien garantir. Bien entendu, il s'agit d'un exercice très simple, le programme est bidon. Peut-être l'as-tu fait consciemment. On peut en douter puisque tu as précisé « débuter », et même si c'est le cas tu aurais dû nous le préciser. Une option pour ce faire aurait été d'introduire un assert(n > 0 && n < BUF_SZMAX) (disponible dans l'en-tête assert.h) à la suite de l'affectation.

    Comment aurais-tu pu faire autrement ? Au minimum valider la valeur entrée via une simple boucle, comme évoqué plus haut. Attention : il est également nécessaire d'introduire une limite supérieure. Veut-on vraiment laisser à l'utilisateur la possibilité de saisir plus de.. mettons cinquante valeurs ? D'autre part, un VLA ne se justifie pas ici : utilise un tableau d'une taille fixe égale à ce nombre maximum de valeurs que tu auras déterminé. Une autre solution bien qu'un peu disproportionnée consisterait à réaliser une allocation sur le tas - dite communément « allocation dynamique » - via malloc qui permettrait de récupérer élégamment d'une erreur d'allocation**.


    * Je te recommande de te renseigner assez tôt dans ton apprentissage sur ces concepts très importants de « pile » (stack) et de « tas » (heap) dans le cadre de l'exécution d'un programme (les structures de données qui portent les mêmes noms n'ont rien à voir). Un bon lien : https://stackoverflow.com/q/79923 .

    ** J'exclue ici la stratégie d'allocation très discutable dite « optimiste » qu'on peut choisir d'activer dans le noyau Linux.

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

Discussions similaires

  1. L'erreur du débutant ?
    Par Enkahel dans le forum Débuter
    Réponses: 1
    Dernier message: 04/05/2007, 10h33
  2. Erreur de débutant
    Par michel71 dans le forum Débuter
    Réponses: 2
    Dernier message: 10/12/2006, 14h21
  3. [SQL] Erreur grand débutant echo / $data
    Par carelha dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 15/05/2006, 12h01
  4. Message d'erreur pour débutant
    Par PhpDeb dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 7
    Dernier message: 27/04/2006, 12h14
  5. erreur de débutant
    Par michel71 dans le forum Delphi .NET
    Réponses: 1
    Dernier message: 08/03/2006, 00h26

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