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 :

[Debutant] Syntaxe de base, mécanisme obscur


Sujet :

C

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 4
    Points : 2
    Points
    2
    Par défaut [Debutant] Syntaxe de base, mécanisme obscur
    Je me lance en autodidacte assez débutant sur le C.

    J'en suis à me familiariser avec les valeurs retournées par une expression quelconque, et sur un exercice je ne comprend pas pourquoi lerésultat est ainsi, pourtant j'ai essayé plusieurs trucs pour vérifier quelques idées.

    Voici le 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
    int N=10, P=5, Q=10;
     
     
     
    N = 5; P = 2;
    printf("Avec N = %d et P = %d on a :\n", N, P);
     
    /* premier cas*/
       Q = N++ > P || P++ != 3;
       printf ("\t'Q = N++ > P || P++ != 3;' donne  : N=%d P=%d Q=%d\n", N, P, Q); 
     
    /*deuxième*/
        Q = P++ != 3 || N++ > P;
      printf ("\t'Q = P++ != 3 || N++ > P;' donne  : N=%d P=%d Q=%d\n", N, P, Q); 
     
    /*troisième*/
      Q = 0 || P++ != 3 || N++ > P;
      printf ("\t'Q = 0 || P++ != 3 || N++ > P;' donne  : N=%d P=%d Q=%d\n", N, P, Q);
    Dans le premier cas il me donne N = 6 P = 2 Q = 1 ; dans le second 6 3 et 1 et dans le dernier 7 4 et 1.


    En fait j'ai testé en inversant l'ordre des deux tests dans l'affectation de Q entre le premier et le second cas. Dans le troisième comme je ne comprennais toujours pas, j'ai essayé de rajouter un test avant pour voir ce que ferai C, mais je n'arrive pas à comprendre...

    Merci bien d'avance

  2. #2
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    En fait, dans cette histoire les opérations de chaque ligne sont stoppées à partir du moment où l'une d'elles retourne vrai.
    Dans le dernier cas, Q=0 équivaut à faux, donc on exécute le suivant, P++!=3.
    Or P vaut 3 avant l'incrémentation, donc n'est pas différent de 3, on passe au dernier qui sera exécuté, N++>P, donc N vaut 7.

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Miles
    En fait, dans cette histoire les opérations de chaque ligne sont stoppées à partir du moment où l'une d'elles retourne vrai.
    Dans le dernier cas, Q=0 équivaut à faux, donc on exécute le suivant, P++!=3.
    Or P vaut 3 avant l'incrémentation, donc n'est pas différent de 3, on passe au dernier qui sera exécuté, N++>P, donc N vaut 7.
    Merci beaucoup Miles !

    Je vient de réaliser que si ça "bug" d'apparence c'est parce que N et P ne sont pas remis à leurs valeurs initiales (5 et 2) au début de chaque cas, si c'est bien ça (je vais tester), je m'excuse bien bas

    Edit : effectivement c'est bien ça, je ne comprenais pas ces résultats car je ne réinitialisais pas entre les 3 cas.

    Mais ce que tu m'as dit est intéressant Miles. Ca veut dire que si on fait pas attention, et qu'on veuille augmenter une variable A tout en réalisant une affectation à la variable Bcomme par exemple suivant cette syntaxe :

    Alors si C != 0 B serai affecté à 1 et le reste ne serai pas évalué ? Ainsi A++ ne serai pas exécuté ?

    merci beaucoup.

  4. #4
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Points : 28 123
    Points
    28 123
    Par défaut
    Bonjour,

    Je pense que tu gagnerasi beaucoup à parenthéser tes expressions !

    Si tu as un compilateur fainéant (et c'est plus que probalement ton cas), un telle expression sera évaluée tant qu'un argument n'est pas faux.

    Le parenthésage est nécessaire, mais el fait de séparer les opérations peut également s'avérer important.

    Personnellement, je ne connais pas les priorités des opérateurs, et ne saurais dire si ton code équivaut à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    B = (C || A);
    A++;
    Ou bien à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    A++;
    B = (C || A);
    Autre exemple :
    est un comportement indéfini (sauf erreur de ma part). Donc attention à la séparation des opérations...

  5. #5
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par Reese
    Alors si C != 0 B serai affecté à 1 et le reste ne serai pas évalué ? Ainsi A++ ne serai pas exécuté ?
    Non, on assigne B à C, et si C est différent de 0, on exécute A++, mais C ne vaut pas forcément 1, il vaut B.

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    D'après ce que j'ai lu si tu met
    Cela équivaut à

    Donc pour ton code avec le tableau, ça devrait être compris par le compliateur mais je veux pas m'affirmer ce n'est que d'après ce que j'ai lu


    J'utilise Dev-C++ car ça avait l'air d'être le plus simple et tout en un. Je ne sais pas si le ocmpilateur est bon, et ce genre de choses, mais jusqu'à maintenant pour des errurs basiques elles sont bien mises en évidence ^^

    Merci beaucoup, je vais faire attention aux parenthèses now.

    Citation Envoyé par Miles
    Citation Envoyé par Reese
    Alors si C != 0 B serai affecté à 1 et le reste ne serai pas évalué ? Ainsi A++ ne serai pas exécuté ?
    Non, on assigne B à C, et si C est différent de 0, on exécute A++, mais C ne vaut pas forcément 1, il vaut B.
    Là je vois pas

  7. #7
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Bonjour,
    Citation Envoyé par gangsoleil
    Si tu as un compilateur fainéant (et c'est plus que probalement ton cas), un telle expression sera évaluée tant qu'un argument n'est pas faux.
    Plus exactement jusqu'à ce que la valeur de l'expression soit connue. Dans ce cas :
    Si C vaut 1 (donc vrai), on s'arrête là, donc le reste n'est pas exécuter.

    Citation Envoyé par gangsoleil
    Personnellement, je ne connais pas les priorités des opérateurs, et ne saurais dire si ton code équivaut à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    B = (C || A);
    A++;
    Ou bien à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    A++;
    B = (C || A);
    Aucune des deux car si C vaut 0 (faux) A n'est pas modifié mais si C vaut 1 (vrai), cela revient au même que la première solution.

    Citation Envoyé par gangsoleil
    Autre exemple :
    est un comportement indéfini (sauf erreur de ma part). Donc attention à la séparation des opérations...
    Exact, on ne sait pas si c'est le membre de droite au celui de gauche qui va être interprété en premier.

  8. #8
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Oups, pardon, dans mon explication, j'ai inversé B et C !!!

  9. #9
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par Reese
    J'utilise Dev-C++ car ça avait l'air d'être le plus simple et tout en un. Je ne sais pas si le ocmpilateur est bon, et ce genre de choses, mais jusqu'à maintenant pour des errurs basiques elles sont bien mises en évidence ^^
    Dev-cpp n'est qu'un IDE (Integrated Development Environment ou environnement de développement intégré en français) il utilise, par défaut, Mingw pour la compilation qui est un portable de gcc sous Windows. Donc au niveau de la qualité du compilateur il n'y a pas de problème.

  10. #10
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Ca fait encore plus peur après le problème que avant. Mais je vais essayer de survivre.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut Re: [Debutant] Syntaxe de base, mécanisme obscur
    Citation Envoyé par Reese
    Je me lance en autodidacte assez débutant sur le C.
    Tu as donc un bon livre de C entre les mains...
    J'en suis à me familiariser avec les valeurs retournées par une expression quelconque,
    Quelqonque ? Certainement pas. Il y a des choses qui sont définies et d'autres qui ne le sont pas (même si la syntaxe est avalée par le compilateur). Ce qui n'est pas défini peut provoquer n'importe quoi. C'est un bug. Il faut cesser de programmer au hasard, apprendre les regles du langage et s'y tenir. (comme ne pas mélangerl es opérateurs unaires et binaires dans la même expression)

  12. #12
    Membre averti

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    289
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 289
    Points : 342
    Points
    342
    Par défaut
    Citation Envoyé par gege2061
    Citation Envoyé par gangsoleil
    Si tu as un compilateur fainéant (et c'est plus que probalement ton cas), un telle expression sera évaluée tant qu'un argument n'est pas faux.
    Plus exactement jusqu'à ce que la valeur de l'expression soit connue. Dans ce cas :
    Si C vaut 1 (donc vrai), on s'arrête là, donc le reste n'est pas exécuter.
    C peut aussi valoir 2, 3 ou 15000... Toute valeur non-nulle est considere comme "vraie" pour les operateurs logiques. L'expression est (presque ?) equivalente a
    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
    /* En C, l'evaluation des && et || est paresseuse, i.e. toujours de gauche a droite, donc on evalue d'abord C */
    if (C != 0)
    {
        /* C est non-nul, donc 'expression est vraie, l'evaluation s'arrete ici, et renvoie la valeur 1 */
        B = 1;
    }
    else
    {
        /* C est nul, donc faux, l'evaluation du OU logique continue */
        /* d'abord on prend la valeur de A */
        if (A == 0)
        {
            /* A nul : faux, donc l'expression prend la valeur 0 */
            B = 0;
        }
        else
        {
            /* A non-nul, donc vrai: l'expression prend la valeur 1 */
            B = 1;
        }
        /* post-incrementation de A */
        A = A + 1;
    }
    ("presque" car j'hesite entre l'ordre d'affectation entre A et B dans le cas C nul)

  13. #13
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par alveric
    ("presque" car j'hesite entre l'ordre d'affectation entre A et B dans le cas C nul)
    C'est bon, l'opérateur d'incrémentation est postfixé donc on commence par évaluer la valeur de A puis on l'incémente.

  14. #14
    Membre averti

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    289
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 289
    Points : 342
    Points
    342
    Par défaut
    Citation Envoyé par gege2061
    Citation Envoyé par alveric
    ("presque" car j'hesite entre l'ordre d'affectation entre A et B dans le cas C nul)
    C'est bon, l'opérateur d'incrémentation est postfixé donc on commence par évaluer la valeur de A puis on l'incémente.
    Je voulais dire, peut-on avoir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        if (A == 0)
        {
            /* post-incrementation de A */
            A = A + 1; 
            /* A nul : faux, donc l'expression prend la valeur 0 */
            B = 0;
        }
        else
        {
            /* post-incrementation de A */
            A = A + 1; 
            /* A non-nul, donc vrai: l'expression prend la valeur 1 */
            B = 1;
        }
    : i.e. une fois que le test est fait, les affectations sont-elles faites dans un ordre precis ?

  15. #15
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par alveric
    i.e. une fois que le test est fait, les affectations sont-elles faites dans un ordre precis ?
    ça m'étonnai aussi que la question soit aussi simple
    ça rejoin le problème de gangsoleil avec son tableau :
    Citation Envoyé par gege2061
    Citation Envoyé par gangsoleil
    Autre exemple :
    Code:

    est un comportement indéfini (sauf erreur de ma part). Donc attention à la séparation des opérations...
    Exact, on ne sait pas si c'est le membre de droite au celui de gauche qui va être interprété en premier.

  16. #16
    Membre averti

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    289
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 289
    Points : 342
    Points
    342
    Par défaut
    Citation Envoyé par gege2061
    Citation Envoyé par alveric
    i.e. une fois que le test est fait, les affectations sont-elles faites dans un ordre precis ?
    ça m'étonnai aussi que la question soit aussi simple

    Citation Envoyé par gege2061
    ça rejoin le problème de gangsoleil avec son tableau :
    Je pense aussi, mais a defaut d'avoir la norme sous les yeux, j'avais un doute si ce cas etait determine ou non. C'est probablement au choix du compilateur, je suppose.

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

Discussions similaires

  1. [Debutant]Compacter la base
    Par tonio-lille dans le forum 4D
    Réponses: 2
    Dernier message: 02/06/2006, 16h48
  2. [Debutant] Eclipse et base de donnees
    Par ms7 dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 24/04/2006, 11h54
  3. SQL-SERVEUR 2000 [debutant] connexion à la base
    Par ducho dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 17/03/2006, 10h05
  4. [debutant] création de base de donnée pour un forum
    Par Pierrick584 dans le forum Débuter
    Réponses: 1
    Dernier message: 01/01/2006, 11h38
  5. debutant syntaxe js
    Par philippe123 dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 16/08/2005, 16h18

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