Conditions if avec virgules

Fermé
lylia - Modifié le 2 avril 2019 à 00:14
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 - 8 avril 2019 à 09:31
salut!
j'ai programmé un jeu en langage c, mais j'ai un petit problème!
car je n'y arrive pas à annuler la condition
((
        if(n==2,3,5,7,11){
                printf("\n les nombres premiers!:");
                scanf("%d",&m);
                printf("\n tres bien!!");          ))

aussi le nombre des chiffres aléatoires affichés n'augmente plus à chque fois que le joueur gagne .
voici le programme:

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<windows.h>

 int T[50],m,n,i,j,x,y,lvl=1,test;
 char ch;
 void init(){
 printf("Etes-vous pret pour ce jeu?\n\n");
 system("pause>null");
 system("cls");
 printf("Trouvez les nombres premiers s'il se trouvent!\n\n");
 for(i=1;i<=50;i++){
   T[i]=-1;
 }
 system("pause>null");
 system("cls");

 }
void job(){
 for(i=0;i<=lvl;i++){
        y=rand()%20;
        x=rand()%41;
        n=rand()%11;
        }
 for(i=1;i<=y;i++){
        printf("\n"); }
 for(j=1;j<=x;j++){
        printf("\t"); }
 printf("%d\n",n);
 T[i]=n;
 Sleep(500);
 system("cls");
}


 int main(){

    srand(time(NULL));
        init();
        while(ch!='l'){
         job();
         printf("les nombres sont:");
         scanf("%d",&m);
         if(m==n){
            if(n==2,3,5,7,11){
                printf("\n les nombres premiers!:");
                scanf("%d",&m);
                printf("\n tres bien!!");
                lvl++;}
            else{
                break;
                }
          }
          else{
              printf("\n Ooops!..\n Vous avez perdu!");
              system("pause>null");
              system("cls");
         }
 ch=getchar();}
                return 0;
         }


Remarque: je suis une débutante en langage c!!

EDIT : Ajout des balises de code (la coloration syntaxique).
Explications disponibles ici : ICI

Merci d'y penser dans tes prochains messages.

3 réponses

[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 2 avril 2019 à 11:02
Bonjour lylia,

Il y a beaucoup de choses qui ne vont pas dans ton code, et il y a aussi des choses qui devraient t'être signalées par ton compilateur sous la forme d'avertissements et qui concernent ta question.

Alors, commençons par cela.

Voilà ce que donne ton code compilé avec
gcc
et les warnings (option
-Wall
)

$ gcc -Wall 35955043.c
35955043.c: In function ‘main’:
35955043.c:46:11: warning: left-hand operand of comma expression has no effect [-Wunused-value]
    if(n==2,3,5,7,11){
           ^
35955043.c:46:13: warning: left-hand operand of comma expression has no effect [-Wunused-value]
    if(n==2,3,5,7,11){
             ^
35955043.c:46:15: warning: left-hand operand of comma expression has no effect [-Wunused-value]
    if(n==2,3,5,7,11){
               ^
35955043.c:46:17: warning: left-hand operand of comma expression has no effect [-Wunused-value]
    if(n==2,3,5,7,11)
                 ^{

Si tu veux que la condition soit vraie si la valeur de
n
est égale à 2, ou à 3 ou à 5 ou à 7 ou à 11, tu devrais utiliser l'opérateur logique
||
qui signifie "ou", et écrire ceci :

if (n == 2 || n == 3 || n == 5 || n == 7 || n == 11) {


Pour le reste, je ne comprends pas très bien ce que doit faire ton programme, ni ce que tu veux dire par "annuler la condition"

Dal
1
lylia03 Messages postés 13 Date d'inscription mardi 2 avril 2019 Statut Membre Dernière intervention 5 avril 2019
2 avril 2019 à 11:21
Merci beaucoup pour votre remarque !
c'était très utile.
Et à propos de mon programme je veux créer un jeu qui tire des chiffres au hasard entre 0 et 10 et qui apparaissent dans des places différentes pendant 500ms puis les récupérer par l'utilisateur et chercher les nombres premiers entre eux s'ils existent sinon la question dernière n'y apparaît plus.
Mais dans chaque niveau normalement le nombre de chiffres tirés doit être augmenté avec 1.
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 2 avril 2019 à 11:49
Rebonjour lylia,

1.

Une petite explication sur le sens de ce que tu as écris :

if(n==2,3,5,7,11){

L'opérateur virgule en C ne fait pas ce que tu penses.

Il se comporte de la façon suivante : ce qui est à gauche de la virgule est évalué, mais le résultat de l'évaluation est ignoré, s'il y a plusieurs virgules à la suite, ce qui est à gauche de la virgule subit le même traitement, puis, ce qui est à droite de la (dernière) virgule est évalué et retourné.

Donc, ce que tu as écrit fait la chose suivante :

- ce qui est à gauche de la première virgule est évalué, mais pas retourné, donc ici
n==2
est évalué, mais le résultat de cette évaluation (vrai ou faux) est ignoré,
- ce qui est gauche de la virgule qui suit
3
est évalué (le C évalue tout entier non nul comme signifiant "vrai"), mais le résultat de cette évaluation est ignoré,
- etc. jusqu'à ce que ce qui est à droite de la dernière virgule
11
soit évalué et soit retourné

Donc l'expression
if(n==2,3,5,7,11){
est en fait équivalente à
if (11) {
, et comme le C évalue tout entier non nul comme signifiant "vrai", le test est toujours vrai.

2.

En principe, lorsqu'on utilise l'opérateur virgule, on met les éléments entre virgules entre parenthèses. Cela évite que les règles de priorité affectées à cet opérateur n'interfèrent avec ce qui est écrit à gauche.

Par exemple, si tu avais écrit
if ( n == (2,3,5,7,11) ) {
la valeur de
n
aurait bien été testée, mais seulement avec la dernière opérande à droite de la (dernière) virgule, et cette ligne aurait, en réalité testé
if (n == 11) {
...

3.

L'opérateur virgule peut servir dans un test à écrire de façon compacte des instructions qui doivent être exécutées, et qui ont un effet de bord qui affecte l'issue du test.

Par exemple, imaginons une boucle
for
, qui doit être initialisée avec deux valeurs
x
et
y
traçant le résultat une fonction sur un intervalle de
x
allant de 0 à 99, on pourrait écrire :

for (x = 0, y = 0; ( parabole(x, &y), x < 100 ); x++)
   draw_point(x, y);

Ce style d'écriture est cependant découragé, car il peut être difficilement compréhensible pour le lecteur.

Dal
0
lylia03 Messages postés 13 Date d'inscription mardi 2 avril 2019 Statut Membre Dernière intervention 5 avril 2019
2 avril 2019 à 11:52
merci encore !
mais ça m'aide seulement à résoudre un seul problème qui est celui que vous avez indiqué auparavant ;et puis l'explication du programme tout entière est au-dessus ;)
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 2 avril 2019 à 12:28
oui, le but de ce 2ème post est d'expliquer comment fonctionne l'opérateur virgule sur ton code, et comment il peut être utilisé correctement en langage C.
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 2 avril 2019 à 13:08
J'ai renommé ton sujet en "Conditions if avec virgules sont toujours vraies", de façon à ce que de futurs utilisateurs faisant une recherche aient de meilleures chances de tomber sur ce post et d'être eux aussi aidés.

Si tu as d'autres problèmes avec ton code, reposte un autre message, avec ton code corrigé, avec un titre explicite par rapport à ton problème (pas "débutant en langage C"). Dans ton message, explique clairement ce que tu voudrais que ton code fasse, ce qu'il fait, et ce que tu n'arrives pas à comprendre ou résoudre. Dis toi que les gens qui te lisent ne sont pas dans ta tête :-)

Quand tu postes du code sur le forum, fais le en utilisant les balises de code du forum. Pour ton message d'origine, un modérateur a modifié ton post pour toi. Lis bien les instructions dans l'encadré bleu laissées par le modérateur dans ton message d'origine pour que tu saches, à l'avenir, comment faire pour poster ton code proprement sur le forum.
0
lylia03 Messages postés 13 Date d'inscription mardi 2 avril 2019 Statut Membre Dernière intervention 5 avril 2019
Modifié le 2 avril 2019 à 15:12
Ah! oui d'accord,
c'est parce que je n'ai jamais posté de messages sur le forum ;)
Mais est ce que vous pouvez m'aider dans mon autre problème dans ce code que j'ai envoyé?
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
2 avril 2019 à 15:38
Oui, bien sûr tu es nouvelle, d'ailleurs bienvenue sur le forum :-)

Si tu as un autre problème que celui concernant ton test if avec des virgules qui donnait toujours "vrai" et qui a motivé ton post initial, poste un autre message sur le forum C, en suivant les indications ci-dessus, et un membre du forum disposant de temps et des compétences t'aidera sûrement, si ce n'est pas moi.
0
lylia03 Messages postés 13 Date d'inscription mardi 2 avril 2019 Statut Membre Dernière intervention 5 avril 2019
Modifié le 4 avril 2019 à 19:45
il m'indique qu'il faut y aller dans les paramètres et spécifier le"gdb.exe" pour mon compilateur GCC;et quand j'y allé je n'ai pas pu le faire car ils sont ensembles (gdb-cdb Default)!
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 5 avril 2019 à 09:52
si tu as téléchargé Codeblocks à partir du site officiel http://www.codeblocks.org/downloads/26 et la bonne version incluant MinGW "codeblocks-17.12mingw-setup.exe) (4ème lien pour Windows), ce paquet d'installation comprend le débogueur GDB, et un fichier gdb32.exe doit se trouver dans le répertoire MinGW/bin de ton répertoire d'installation.

Le menu à utiliser et la façon de le compléter pour que le débogueur fonctionne est précisée ici : http://wiki.codeblocks.org/index.php?title=MinGW_installation#Code::Blocks_Configuration en cliquant sur "Default" sous "GDB/CDB debugger"... mais, normalement, si tu as installé le paquet ci-dessus, cette configuration se fait toute seule.

Si ce n'est pas le cas et que tu as GDB sur ton système, indique l'emplacement de gdb32.exe, et précise que ton type de débogueur est GDB, coche les cases comme indiqué dans le lien et valide.

Si tu n'as pas installé Codeblocks avec le paquet indiqué ci-dessus, mais que tu as fait autrement, peut être devrais-tu désinstaller ce que tu as installé, et installer le bon paquet pour te simplifier la vie.

Dal
0
lylia03 Messages postés 13 Date d'inscription mardi 2 avril 2019 Statut Membre Dernière intervention 5 avril 2019
5 avril 2019 à 15:41
je sais bien que je vous ai déranger mais SVP si vous pouvez voir mon nouveau code pour ce programme et me corriger mes fautes
car le lvl s'incrémente normalement et après la première victoire il m'affiche normalement cette instuction
printf("N°%d",k);
scanf("%d",m)
deux fois bien sûr avec l'incrémentation du nombre des chiffres.
mais après ça elle ne fonctionne pas!
0
lylia03 Messages postés 13 Date d'inscription mardi 2 avril 2019 Statut Membre Dernière intervention 5 avril 2019
5 avril 2019 à 15:48
voici alors le code
#include<stdio.h>
#include<time.h>
#include<windows.h>
#include<stdlib.h>
#include<stdbool.h>

int lvl=1,i,j,k,n,m,x,y,t[50],test=0;
char ch;

void init();
void job();
bool job2();

void init(){
   printf("voulez-vous essayer ce jeu?");
    Sleep(1000);
     system("cls");
      printf("\n Donc soyez rapides!!");
       Sleep(1000);
        system("cls");

   for(i=0;i<=30-1;i++){
            t[i]=-1;
   }
}
void job(){
    for(k=1;k<=lvl;k++){
            y=rand()%20;
            x=rand()%41;
            n=rand()%11;
    for(i=1;i<=y;i++){
        printf("\n");}
    for(j=1;j<=x;j++){
            printf("\t");}
    printf("%d",n);
    t[i]=n;
     Sleep(500);
      system("cls");
    }
}
bool job2(){
    test=1;
    printf("saisissez les nombres apparus!");
    for(k=1;k<=lvl;k++){
        printf("\n N°%d:",k);
        scanf("%d",&m);

        if(m!=n){
        test=0;
        break;
        }
    }

return test;
}




int main(){
srand(time(NULL));
init();
while(ch!='l'){
 job();
        if(job2()!=0){
            printf("\n Bravo!");
            lvl++;
            }
        else{
            printf("\n Vous avez perdu!");
        }
printf("\n Soyez prêt!");
 ch=getchar();
 }
return 0;
 }


0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 8 avril 2019 à 09:41
En ligne 48 ci-dessus, tu ne fais que ce test là pour la valeur saisie :
if(m!=n){
.

Donc, de nouveau, tu ne testes pas la valeur saisie
m
par rapport à toutes les valeurs tirées au sort présentes dans le tableau
t
.

Pour faire cela, que ferais-tu si tu devais le faire avec un papier et un crayon ?

Moi, je ferais comme cela :

1- je demande la saisie d'une valeur
m
,
2- je garde à l'esprit
m
,
3- je passe en revue ce que contient le tableau
t
,
4- si le tableau
t
contient la même valeur
m
saisie, je barre cette valeur dans
t
,
5- si le tableau ne contient pas la même valeur
m
saisie, l'utilisateur s'est trompé et je sors de la fonction avec un code d'erreur,
6- si l'utilisateur doit encore saisir des valeurs, le répète à partir de 1-,
7- sinon, c'est que toutes les valeurs saisies
m
ont été barrées dans
t
et que l'utilisateur a tout bon, et je sors de la fonction avec un code de succès.
0