Répondre à la discussion
Page 1 sur 2 1 DernièreDernière
Affichage des résultats 1 à 30 sur 42

Les boucles ......



  1. #1
    frequi1

    Les boucles ......


    ------

    Bonjour,

    Déja voila le code, j'ai juste un petit ennui pour placer un boucle
    Code:
     #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main()
    {
        int A=1, choix =1;
         while (A)
        {
             char essai[100] ,essai2[100];
             printf("Ecris un mot :\n");
             scanf ("%s", essai);
             strcpy(essai2,essai);
             int longueur = 0;
             longueur = strlen (essai);
             printf("\nLe mot %s, est compose de %d lettres\n", essai, longueur);
             printf ("%s\n", essai2);
            
                printf ("\nEncore\n1.OUI\n2.NON\n");
                scanf ("%d", &choix);
    
                if (choix == 1)
                A=1;
                else if (choix == 2)
                A--;
                else
                {
                do
                {
                printf("Choix incorrect, Reformuler votre choix :");
                }while(choix==1 || choix==2);
    
         }     }
             return 0;
     }
    Voila a la fin du programme on demande si on veux recommencer depuis le début par un choix 1=OUI et 2 = NON et pas d'autre choix possible ni 4 ni 8 ni rien, alors que le programme fait comme si on avais répondu 1(OUI) . Je pense que ce n'est qu'un mauvais placement d'une boucle mais je ne trouve pas .Quelqu'un pourra peut être m'orienter.

    -----

  2. Publicité
  3. #2
    PA5CAL

    Re : Les boucles ......

    Bonjour

    Telle que ta boucle est placée actuellement, et compte tenu du test pratiqué pour en sortir, elle se contente d'afficher le message puis quitte immédiatement (puisque dans ce cas de figure, la variable « choix » n'est ni égale à 1, ni égale à 2).

    La boucle qui attend le choix 1 ou 2 doit nécessairement contenir le « scanf ("%d", &choix); ». Et on doit recommencer cette boucle tant que la variable « choix » est différente de 1 ET différente de 2.

    Comme tu testes déjà la variable « choix » pour les valeurs 1 et 2, il serait plus simple d'utiliser carrément une instruction « continue; » après le dernier « else », et de quitter la boucle dans la boucle quand tout se passe bien, en recourant à une boucle « while(1){ ... break;} » ou à une boucle « do{ ... }while(0); ».
    Dernière modification par PA5CAL ; 09/10/2012 à 12h27.

  4. #3
    PA5CAL

    Re : Les boucles ......

    Oups... il faut lire :

    ... " et de quitter la boucle quand tout se passe bien, en recourant à une boucle « while(1){ ... break;} » ou à une boucle « do{ ... }while(0); ». "

  5. #4
    frequi1

    Re : Les boucles ......

    Bravo PA5CAL t'es un chef merci

  6. #5
    frequi1

    Re : Les boucles ......

    Ai je un problème avec les algorithme ?

  7. A voir en vidéo sur Futura
  8. #6
    PA5CAL

    Re : Les boucles ......

    Re-oups... J'ai été un peu vite.

    On ne peut pas utiliser de « continue; » pour recommencer dans le cas d'une boucle « do{ ... }while(0); ». Il faut donc seulement retenir la solution de la boucle « while(1){ ... break;} ».

  9. Publicité
  10. #7
    frequi1

    Re : Les boucles ......

    non pas du tou j'ai modifier le code avec ton premier message et il a fonctionner direct
    Code:
     #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main()
    {
        int A=1, choix =1;
         while (A)
        {
             char essai[100] ,essai2[100];
             printf("Ecris un mot :\n");
             scanf ("%s", essai);
             strcpy(essai2,essai);
             int longueur = 0;
             longueur = strlen (essai);
             printf("\nLe mot %s, est compose de %d lettres\n", essai, longueur);
             printf ("%s\n", essai2);
                do
                {
                printf ("\nEncore\n1.OUI\n2.NON\n");
                scanf ("%d", &choix);
    
                if (choix == 1)
                A=1;
                else if (choix == 2)
                A--;
                else
                {
                 printf("Choix incorrect, Reformuler votre choix :");
                }}while(choix!=1 && choix!=2);
    
         }
             return 0;
     }
    CA marche tres bien ....

  11. #8
    PA5CAL

    Re : Les boucles ......

    Citation Envoyé par frequi1 Voir le message
    Ai je un problème avec les algorithme ?
    Que veux-tu dire par là ?

    Tu débutes, et tu fais des erreurs de débutant, les mêmes que moi quand j'ai commencé la programmation (je me faisais d'ailleurs justement la remarque). Il n'y a rien d'inquiétant à cela. Je pense que c'est en pratiquant que tu acquerras les connaissances, la rigueur et les réflexes nécessaires.

  12. #9
    PA5CAL

    Re : Les boucles ......

    Citation Envoyé par frequi1 Voir le message
    non pas du tou j'ai modifier le code avec ton premier message et il a fonctionner direct.
    Je me plaçais dans l'hypothèse où l'on éviterait de refaire le test sur la valeur de « choix ». En effet, ici tu le fais deux fois, dans le « if » et dans le « while ».

    Considère plutôt ceci :
    Code:
        while(1)
        {
            printf ("\nEncore\n1.OUI\n2.NON\n");
            scanf ("%d", &choix);
    
            if (choix == 1)
                A=1;
            else if (choix == 2)
                A--;
            else
            {
                printf("Choix incorrect, Reformuler votre choix :");
                continue;
            }
    
            break;
        }
    ou encore cela :
    Code:
        while(1)
        {
            printf ("\nEncore\n1.OUI\n2.NON\n");
            scanf ("%d", &choix);
    
            if (choix == 1)
            {
                A=1;
                break;
            }
    
            if (choix == 2)
            {
                A--;
                break;
            }
    
            printf("Choix incorrect, Reformuler votre choix :");
        }

  13. #10
    frequi1

    Re : Les boucles ......

    PA5CAL
    Je tiens a te remercier pour toutes les aides que tu m'apportes, c'est vraiment super et je me vois avancer. Tu ne donnes pas les réponses et tu me laisse réfléchir a mes problèmes.
    C'est ton métier peut être la pédagogie ?
    Tu étais la dans ma dernière discussions sur les tableau et tu es la pour mon chapitre sur les chaines de caractères.
    J'attaque bientôt les structures, ça risque d’être un peu plus chaud la non ?

    Et encore merci a toi ....
    Code:
     break;
    c'est quoi son role a lui. je ne l'ai vu que dans les switch.
    Dernière modification par frequi1 ; 09/10/2012 à 12h58.

  14. #11
    PA5CAL

    Re : Les boucles ......

    Citation Envoyé par frequi1 Voir le message
    C'est ton métier peut être la pédagogie ?
    Non, pas du tout. En revanche, arriver à faire comprendre des notions nouvelles à mes interlocuteurs fait bien partie de mon travail.

    Citation Envoyé par frequi1 Voir le message
    J'attaque bientôt les structures, ça risque d’être un peu plus chaud la non ?
    Non, pas plus que le reste. Il « suffit » juste de découvrir et de comprendre.

    Citation Envoyé par frequi1 Voir le message
    Code:
     break;
    c'est quoi son role a lui. je ne l'ai vu que dans les switch.
    Ça sert à interrompre l'exécution d'un bloc d'instructions (typiquement une boucle « for() », « while() » ou « do...while(); » ou un « swich(){ case: ...} ») et de continuer après la fin de ce bloc.

    C'est donc une instruction très pratique pour sortir d'une boucle.

    Note au passage que l'instruction « goto » est très mal vue en langage C (parce qu'il est conçu pour faire de la programmation structurée, et non pas bêtement séquentielle comme BASIC par exemple), et que « break; » permet de la remplacer avantageusement dans certains cas de figure. Par exemple, un bout de programme du type :
    Code:
     ...
        if (i<0)
            goto suite;
     ...
        if (j>100)
            goto suite;
     ...
        if (k!=i)
            goto suite;
     ...
    /* suite du programme */
    suite:
     ...
    peut être codé ainsi :
    Code:
    while(1)
    {
     ...
        if (i<0)
            break;
     ...
        if (j>100)
            break;
     ...
        if (k!=i)
            break;
     ...
        break;
    }
    /* suite du programme */
     ...
    (NB: surtout ne pas oublier le « break; » juste avant la fin du « while(1){...} »)
    Dernière modification par PA5CAL ; 09/10/2012 à 13h23.

  15. #12
    PA5CAL

    Re : Les boucles ......

    ... En fait on évite surtout les « goto » parce qu'une erreur dans son utilisation mène à des dysfonctionnement graves du fait d'une mauvaise interprétation de l'état de la pile. Ce n'est alors plus le programme du développeur qui déraille, mais carrément le fonctionnement de base prévu par le langage, et on peut rencontrer de très grandes difficultés pour déboguer ce type d'erreur.
    Dernière modification par PA5CAL ; 09/10/2012 à 13h32.

  16. Publicité
  17. #13
    frequi1

    Re : Les boucles ......

    alors la tu vois :
    des dysfonctionnement graves du fait d'une mauvaise interprétation de l'état de la pile
    qu'est ce que tu appelle la pile ?
    et aussi l'état de la pile ?

    j'ai peut être pas encore le niveau.....

  18. #14
    PA5CAL

    Re : Les boucles ......

    Là on entre dans le fonctionnement intime du langage C. Ce n'est pas vraiment utile de le connaître dans un premier temps, mais il sera nécessaire d'y passer pour comprendre la raison de faire de certaines manipulations de données (ou plutôt pourquoi certaines façons de faire sont irréalisables).

    La pile est un espace de mémoire dans laquelle sont automatiquement rangées les variables locales et les données passées en arguments à la fonction en cours, et les adresses de retour de la fonction appelante.

    Cet espace mémoire est géré un peu comme une pile d'assiettes : pour rajouter de nouvelles assiettes on les met sur le dessus de la pile, et on doit enlever les assiettes du dessus pour manipuler normalement les assiettes plus anciennes situées au-dessous. (L'image est assez exacte, à ceci près que la pile commence normalement à la fin de la mémoire vive disponible, et progresse en direction du début... c'est plutôt l'équivalent d'une pile d'assiettes qu'on colle au plafond).

    L'avantage de cette structure, c'est que lorsqu'on manipule les données situées près du dessus de la pile, on n'a pas à connaître le nombre données déjà empilées (comme ce serait le cas pour un tableau par exemple). En langage C, la pile est manipulée au travers de pointeurs dédiés qui restent inaccessibles à l'utilisateur, le mécanisme mis en oeuvre est automatiquement mis en oeuvre au travers de la compilation.

    On trouve de nombreuses explications illustrées et en français à ce sujet sur Internet.
    Dernière modification par PA5CAL ; 09/10/2012 à 14h35.

  19. #15
    JPL

    Re : Les boucles ......

    Le point important est que cette pile n'offre qu'un espace limité et que dans une programmation malhabile elle peut déborder, comme une pile d'assiettes qui serait plus haute que la cuisine (message : stack overflow ).
    Rien ne sert de penser, il faut réfléchir avant - Pierre Dac

  20. #16
    PA5CAL

    Re : Les boucles ......

    Citation Envoyé par JPL Voir le message
    (message : stack overflow ).
    Et sur certaines plateformes, il arrive qu'il n'y ait pas de message du tout : l'ordinateur déraille de temps en temps, un peu n'importe quand, sans qu'on sache a priori pourquoi.
    Dernière modification par PA5CAL ; 09/10/2012 à 14h50.

  21. #17
    PA5CAL

    Re : Les boucles ......

    On peut aussi préciser que la pile ne sert pas qu'au programme exécuté, mais est également utilisé pour le fonctionnement de l'ensemble de la machine.

    Ainsi, quand un événement matériel (par exemple la réception de données sur un port d'entrées/sorties) génère une interruption et provoque l'exécution d'une routine de traitement adaptée, c'est sur la pile que sont stockées l'adresse du code où l'exécution normale doit reprendre, et les variables temporaires nécessaires à cette routine d'interruption.

    Il doit donc toujours rester sur la pile suffisamment de place, en plus de celle prévue pour le fonctionnement de son propre programme, pour les traitements réalisés par les autres sous-systèmes de l'ordinateur.
    Dernière modification par PA5CAL ; 09/10/2012 à 15h11.

  22. #18
    PA5CAL

    Re : Les boucles ......

    Pour donner un exemple de programmation malhabile que JPL évoquait, voici un exemple de fonction récursive, qui remplit la pile autant que nécessaire jusqu'à son débordement:
    Code:
    long f(long a)
    {
    	if (a>0)
    		return 1 + f(a-1);
    	else
    		return 0;
    }
    Calculer « f(10); » ne devrait pas poser de problème. En revanche, tenter de calculer « f(2000000000); » remplit la mémoire en faisant exploser la pile ...
    Dernière modification par PA5CAL ; 09/10/2012 à 15h21.

  23. Publicité
  24. #19
    Jack

    Re : Les boucles ......

    Il doit donc toujours rester sur la pile suffisamment de place, en plus de celle prévue pour le fonctionnement de son propre programme, pour les traitements réalisés par les autres sous-systèmes de l'ordinateur.
    En principe, chaque processus possède son propre espace de pile.

    A+

  25. #20
    PA5CAL

    Re : Les boucles ......

    Citation Envoyé par Jack Voir le message
    En principe, chaque processus possède son propre espace de pile.
    Cela n'est vérifié que sur certaines plateformes, et souvent sur celles de taille importante (avec une pile de taille confortable) et qui possèdent une gestion matérielle du dépassement de pile.

    Sur la majorité des plateformes où la taille de la pile est extrêmement problématique et requiert toute l'attention du programmeur en langage C, les interruptions entrent dans le décompte du volume occupé par la pile et par le tas (les deux étant le plus souvent situés dans le même espace mémoire).

    Cette évaluation est d'autant plus critique sur les petits systèmes qui ne possèdent pas de détection matérielle de dépassement de pile qu'il ne peuvent généralement pas non plus se permettre une détection logicielle systématique pour des questions de performances.
    Dernière modification par PA5CAL ; 09/10/2012 à 17h59.

  26. #21
    Jack

    Re : Les boucles ......

    Cela n'est vérifié que sur certaines plateformes
    Je parlais effectivement de la gestion des processus pour des systèmes d'exploitation comme windows ou unix.

    Pour le reste, la gestion de pile peut être angoissante sur des petits microcontrôleurs. Les PIC midrange de microchip sont difficilement exploitatables en C en raison de leur profondeur de pile riquiqui.

    A+

  27. #22
    PA5CAL

    Re : Les boucles ......

    Quoi qu'il en soit, on doit considérer que l'espace dans lequel la pile progresse est constituée :
    - d'une partie occupée, au contenu valide et à la localisation déterminée, remplie par le fonctionnement du programme
    - d'une partie libre utilisable par le système et inutilisable par le programme, au contenu incertain et a priori modifiable sans préavis.

    Par conséquent, on doit s'interdire de stocker des informations comme ceci :
    Code:
    /* MAUVAIS EXEMPLE, À NE PAS REPRODUIRE */
    
    char *base36(unsigned int val)
    {
        char str[8];
        unsigned int num;
    
        for( i=0; i<7; i++ ) {
            num = val%36;
            val /= 36;
            str[6-i] = (num>9 ? 'A'-10 : '0')+num;
        }
        str[7] = '\0';
    
        return str;
    }
    Le tableau de caractères « str » dans lequel est retourné le résultat est stocké dans la partie de la pile devenue invalide après le retour de la fonction. Tout semble bien se passer tant que cette partie libre de pile n'est pas écrasée par un autre contenu... Le problème peut donc rester inaperçu très longtemps, et le résultat ne devenir faux que dans certaines situations pas toujours systématiques, et parfois très difficilement reproductibles.

    C'est le genre de bogue sur lequel on peut rester longtemps à chercher sans rien trouver. Il vaut donc mieux traiter le mal préventivement, en en parlant avant de coder.

    J'ai eu ce cas à traiter sur un programme en C de quelques dizaines de milliers de lignes réalisé par des universitaires, qui n'a commencé à donner des signes de mauvais fonctionnement évidents (et particulièrement catastrophiques) qu'une année après avoir été livré au client. J'ai bien dû passer une semaine (journées, nuits blanches et weekend) avant de trouver l'origine du problème et de pouvoir dépanner le client dont l'activité avait dû être stoppée.
    Dernière modification par PA5CAL ; 09/10/2012 à 18h50.

  28. #23
    PA5CAL

    Re : Les boucles ......

    Citation Envoyé par Jack Voir le message
    Les PIC midrange de microchip sont difficilement exploitatables en C en raison de leur profondeur de pile riquiqui.
    Effectivement, avec seulement quelques octets disponibles pour la pile, ces PICs font figure de cas pathologiques, et le compilateur C qu'il est possible d'utiliser pour leur developpement fait vraiment figure d'ersatz compte tenu du code très particulier qu'il est amené à produire.

    Ce n'est heureusement pas le cas de tous les petites systèmes (à CPU ou à µC), qui souvent disposent de quelques centaines d'octets, voire de plusieurs kilo-octets, pour stocker leur pile et la faire fonctionner comme prévu par les standards.
    Dernière modification par PA5CAL ; 09/10/2012 à 19h06.

  29. #24
    kwariz

    Re : Les boucles ......

    Bonjour,

    waouh
    On part loin du problème de frequi1, qui doit s'arracher les cheveux sur l'algorithmique plus que sur la taille de sa pile comme il est certainement soit sous windows, linux ou osx ...

    @PA5CAL : normalement ton exemple devrait générer un warning par le compilo car c'est un comportement non défini d'utiliser une variable après sa lifetime (temps de vie en Français ?)

  30. Publicité
  31. #25
    PA5CAL

    Re : Les boucles ......

    Citation Envoyé par kwariz Voir le message
    @PA5CAL : normalement ton exemple devrait générer un warning par le compilo car c'est un comportement non défini d'utiliser une variable après sa lifetime (temps de vie en Français ?)
    Ça dépend malheureusement du compilateur et de ses options. Et à l'époque, la compilation du code bogué sur la plateforme qui nous était imposée ne donnait ni erreur ni warning. Si ça avait été le cas, le programme n'aurait même pas été autorisé à passer les tests et n'aurait pas été livré au client.
    Dernière modification par PA5CAL ; 09/10/2012 à 23h00.

  32. #26
    PA5CAL

    Re : Les boucles ......

    Citation Envoyé par kwariz Voir le message
    waouh
    On part loin du problème de frequi1, qui doit s'arracher les cheveux sur l'algorithmique plus que sur la taille de sa pile comme il est certainement soit sous windows, linux ou osx ...
    On n'est pas très loin de l'interrogation de frequi1 sur ce que sont la pile, son fonctionnement et les types de problèmes qu'on peut y rencontrer.

    Par ailleurs, la programmation en langage C dont il est question ici ne s'adresse pas qu'aux OS de PC (au sens large) les plus courants, et même en ce qui les concerne, les questions relatives à la pile ne peuvent pas être passées éludées. En effet, pouvoir disposer d'une pile de 4 Go et d'une trap de stack overflow ne permet absolument pas de garantir le bon fonctionnement d'un programme, et les aides incluses dans les outils de développement ne détectent pas tous les problèmes potentiels non plus. Quand on s'en remet à ces seuls garde-fous, ce n'est pas de la programmation de qualité professionnelle qu'on fait, mais du bricolage.

  33. #27
    kwariz

    Re : Les boucles ......

    C'était une remarque dans le cadre que frequi1 nous a présenté ... il suit un tuto du site du zero pour apprendre à programmer en c, il a apparemment peu de notions en algorithmique et en architecture des ordinateurs. Je pense qu'il découvrira ça au fur et à mesure des ses essais (et surtout de ses plantages comme chacun de nous).
    Évidemment je ne préconise pas de résoudre un problème de stack overflow par une adaptation de la taille de la pile, bien au contraire. Néanmoins je pense qu'il a d'autres priorités que de se soucier des problèmes de pile pour l'instant (il ne développe pas sur un z80 ou un uC).

  34. #28
    PA5CAL

    Re : Les boucles ......

    Citation Envoyé par kwariz Voir le message
    Néanmoins je pense qu'il a d'autres priorités que de se soucier des problèmes de pile pour l'instant
    Ce soucis va venir très vite, puisqu'on a déjà parlé des tableaux et des pointeurs, et qu'on va bientôt aborder la question des structures. Il faudra donc parler de leur stockage, de leur passage comme paramètre ou comme valeur de retour dans les fonctions. Aborder la notion de pile permet justement de comprendre ce qui se passe concrètement, et ce qu'on peut ou ne doit pas faire dans ce domaine.

    Je pense que faire état d'erreurs assez communes (comme celles citées aux posts #15/18 et #22) en les expliquant, constitue une bonne entrée en matière et un moyen certainement efficace pour éviter de reproduire ces fautes par la suite.

    Par ailleurs, si frequi1 a d'autres priorités, il peut très bien revenir plus tard lire ce qui a été présenté ici.
    Dernière modification par PA5CAL ; 10/10/2012 à 00h31.

  35. #29
    kwariz

    Re : Les boucles ......

    Sans vouloir entrer dans une polémique sans fin, je trouve simplement prématuré d'introduire les notions de pile, ou de goto (dès les posts #11/#12) alors que frequi1 à d'autres problèmes (comment utiliser ou imbriquer des boucles). Personnellement je trouve déjà un peu limite d'utiliser des while(1) avec des breaks et des continue avant de comprendre qu'on peut s'en passer ... mais bon, je ne suis ni pédagogue ni enseignant. Je prends juste l'habitude de ne pas mettre la charrue avant les boeufs et de ne pas noyer un apprenant sous une tonne d'informations qu'il n'est pas encore capable de retenir ou de comprendre.
    Dernière modification par kwariz ; 10/10/2012 à 00h38.

  36. #30
    PA5CAL

    Re : Les boucles ......

    Pour le « goto », j'en ai parlé pour éliminer définitivement le sujet, en expliquant pourquoi. Quant au « while(1) », au « continue » et au « break », ce sont des éléments de langage qui répondent directement à des problèmes d'algorithmie, et qui doivent de ce fait être vus assez rapidement.

    De plus, dès lors que leur évocation répond à un problème posé ou à des interrogations qui peuvent être traitées, il n'y a pas de raison de les passer sous silence. Au contraire, quand une question se pose concrètement, suscite intérêt et concentration et peut être réglée assez rapidement, alors c'est le meilleur moment pour le faire, quand bien même cela ne correspondrait pas à la chronologie prévue par le cours suivi.

Sur le même thème :

Page 1 sur 2 1 DernièreDernière

Discussions similaires

  1. les boucles et les coudes dans une proteine
    Par natilus dans le forum Biologie
    Réponses: 2
    Dernier message: 19/10/2011, 14h50
  2. Boucles médiévales
    Par Tresmals dans le forum Archéologie
    Réponses: 5
    Dernier message: 17/04/2011, 09h37
  3. Réponses: 31
    Dernier message: 23/02/2011, 14h45
  4. une corde dans les boucles ? (string + LQG)
    Par doul11 dans le forum Physique
    Réponses: 4
    Dernier message: 22/04/2010, 10h37
  5. Réponses: 3
    Dernier message: 12/11/2007, 16h35