Menu

Conditions if avec virgules

-
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.
Afficher la suite 

Votre réponse

3 réponses

Meilleure réponse
Messages postés
5052
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
24 avril 2019
931
1
Merci
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

Dire « Merci » 1

Heureux de vous avoir aidé ! Vous nous appréciez ? Donnez votre avis sur nous ! Evaluez CommentCaMarche

CCM 40372 internautes nous ont dit merci ce mois-ci

lylia03
Messages postés
13
Date d'inscription
mardi 2 avril 2019
Statut
Membre
Dernière intervention
5 avril 2019
-
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.
Commenter la réponse de [Dal]
Messages postés
5052
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
24 avril 2019
931
0
Merci
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
[Dal]
Messages postés
5052
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
24 avril 2019
931 -
tu dois probablement juste remplacer les

}}

par des

      }
}

pour que le plugin de Codeblocks s'y retrouve et reformate correctement.

Comme je te l'ai dit, dans ton
main()
, tu n'utilises pas la variable globale tableau
T
où tu stockes les numéros. Tu ne compares qu'avec
n
, qui comprend le dernier numéro tiré au sort. Si tu n'utilises pas le tableau, tu ne risques pas de vérifier que ce que l'utilisateur a saisi comprend bien tous les numéros tirés au sort dès que la saisie en comprend plusieurs.

Lorsque l'on programme, il est bon d'avoir une idée de l'algorithme que l'on veut mettre en place, lequel peut écrit de différentes façons, par exemple, en français...

Pour démarrer, un algorithme simplifié pour ton programme, si j'ai bien compris ton jeu, pourrait être comme ceci :

1. initialiser
2. lancer
job()
, qui va stocker dans le tableau
T
les
lvl
nombres tirés au sort qu'il a vu sur l'écran
3. demander à l'utilisateur de saisir les
lvl
nombres qu'il a vu et stocker ces nombres dans un autre tableau, par exemple un
int saisie[50];
...
4. vérifier que chacun des
lvl
nombres saisis contenu dans ce tableau est présent dans le tableau
T
...
5. tirer les conséquences de cette vérification
6. prévoir comment on sort du jeu : niveau maximum atteint (attention à ne pas dépasser la capacité des tableaux), le joueur a perdu trop de fois, le joueur en a assez et veut arrêter, etc.
7. boucler sur 2. sauf si on est sur une condition de sortie
8. terminer le programme

Une fois que tu as mis en place cela, tu peux ajouter une fonctionnalité nouvelle consistant à demander à l'utilisateur s'il pense que des nombres premiers sont sortis et lui demander d'indiquer lesquels.

Mais, déjà, ton code actuel ne fait pas ce que l'algorithme simplifié est supposé faire.

Commence avec des choses simples, teste et met cette chose simple au point, lorsque cela fonctionne, ajoute une fonctionnalité simple, teste et met cette chose simple additionnelle au point, etc.
lylia03
Messages postés
13
Date d'inscription
mardi 2 avril 2019
Statut
Membre
Dernière intervention
5 avril 2019
-
je veux dire par évaluer une fonction de la mettre dans une condition "if" , si c'est possible?
et pour ce que vous avez dit je vais essayer alors de décomposer mon code et le simplifier le plus possible
[Dal]
Messages postés
5052
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
24 avril 2019
931 -
tu peux tout à fait créer une fonction dont le résultat sera utilisé dans un test
if
et tu peux mettre l'appel à cette fonction dans la condition évaluée par le
if
si la fonction retourne quelque chose au lieu d'avoir un prototype
void
.

Par exemple, si tu crées une fonction
int est_premier(int entier);
qui prend en paramètre un entier, et retourne 0 si l'entier n'est pas premier (
return 0;
) et 1 (ou autre chose) si l'entier est premier, tu peux faire un test comme ceci :

    if (est_premier(m)) {
        /* TODO */
    }

cela fonctionne car toute autre valeur que 0 est évaluée à "vrai" en C.

tu peux aussi écrire comme cela, avec le même effet :

    if (est_premier(m) != 0) {
        /* TODO */
    }

ou en faisant un
#include <stdbool.h>
(avec un compilateur à la norme du C99) :

    if (est_premier(m) == true) {
        /* TODO */
    }

(en faisant des
return true;
ou
return false;
dans la fonction, utilsant ces mots clefs introduits dans le norme du C depuis le C99, et tu peux aussi changer le prototype d'une telle fonction en
bool est_premier(int entier);
pour faire usage aussi de ce type introduit par cette même norme pour la valeur de retour)
lylia03
Messages postés
13
Date d'inscription
mardi 2 avril 2019
Statut
Membre
Dernière intervention
5 avril 2019
-
Désolée pour ce dérangement!
merci pour votre aide :)
....mais j'ai suivi tous ce que vous m'avez dit mais le problème avec
lvl++
n'a pas l'air de se réparer, il ne s'incrémente plus!!
[Dal]
Messages postés
5052
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
24 avril 2019
931 -
Il faut déboguer ton code.

Si tu utilises Codeblocks, comme je le pense avec MinGW, le débogueur te permet d'exécuter pas à pas le code et de voir ce que fait vraiment ton code.

Pour démarrer une session de débogage met ton curseur sur la ligne où tu veux que l'exécution s'arrête, par exemple la première ligne de main contenant
srand(time(NULL));
, puis fait :
Debug - Toggle breakpoint
(ou appuie sur F5) pour mettre un point d'arrêt.

Puis fait
Debug - Start / Continue
(ou F8). Cela démarrera le débogueur et exécutera ton code jusqu'à la ligne en question.

Appuie ensuite successivement sur F7 (ou
Debug - Next line
) pour passer à la ligne suivante.

Le débogueur te permet aussi de suivre l'exécution des fonctions, de consulter la valeur de variables, etc.

Apprend à l'utiliser :-)
Commenter la réponse de [Dal]
Messages postés
13
Date d'inscription
mardi 2 avril 2019
Statut
Membre
Dernière intervention
5 avril 2019
0
Merci
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)!
[Dal]
Messages postés
5052
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
24 avril 2019
931 -
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
lylia03
Messages postés
13
Date d'inscription
mardi 2 avril 2019
Statut
Membre
Dernière intervention
5 avril 2019
-
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!
lylia03
Messages postés
13
Date d'inscription
mardi 2 avril 2019
Statut
Membre
Dernière intervention
5 avril 2019
-
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;
 }


[Dal]
Messages postés
5052
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
24 avril 2019
931 -
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.
Commenter la réponse de lylia03