See site in english Voir le site en francais
Website skin:
home  download  forum  link  contact

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

Author Topic: Petite question en C  (Read 2984 times)

0 Members and 1 Guest are viewing this topic.

Offline Bibi Uncle

  • Legend
  • ******
  • Posts: 2264
  • Country: Canada ca
  • Karma: 17
15 June 2010, 19:42:22
Bonjour à tous !

Ma question n'est pas pour un add-on pour Orbiter mais juste pour de la programation personnelle.

Voilà, j'apprend le C (pour apprendre ensuite le C++) sur le Site du Zér0. Dans le premier TP, on fait un petit jeu appellé "Plus ou Moins". Je crois que vous n'avez pas besoin de dessin pour savoir c'est quoi.

Je fais le programme standard, puis j'ai ajouté un mode pour 2 joueurs, un e sélection de difficulté pour le mode 1 joueur, une écran titre, une boucle pour pouvoir recommencer comme on veut le jeu sans réouvrir le jeu ou cliquer sur le "X" pour pouvoir arrêter l'exécutable. Ce matin, j'ai voulu ajouter des "Clear Home" [ <--language TI-BASIC :badsmile: ] et j'ai trouvé la fonction "system("cls");". Puis, j'ai voulu ajouter une autre fonction ( dans un autre fichier .c ) pour pouvoir analyser si la saisie de l'utilisateur est bonne. Mais là, j'ai eu un problème de compilation. En changeant un peu le code, j'ai réussi à règler le problème mais je ne comprend toujours pas pourquoi ça ne marchait pas...

Voilà l'ancien code :

main.c :
Code: [Select]
#include
#include
#include

void affichage(int nombreMystere);

int test(int min, int max, int nombreEntre);

int main(int argc, char *argv)
{

// Écran de présentation

printf("=== Le Jeu Plus ou Moins ===\n\nCree par Emile Gregoire\n\nD'apres une idee du Site du Zer0\n\n\n");

  // Boucle pour recomencer la partie

    int continuerPartie = 1;
    while (continuerPartie)
    {

    // Initialisation des varaibles

    int MAX = 100, MIN = 1; // Nombre aléatoire
    int nombreMystere, choixJeu, difficulte, continuer, test;

    // Choix du mode de jeu
    do
    {
    printf("\nCombien de joueur etes-vous ? (1 ou 2) ");
    scanf("%d", &choixJeu);
    test(1,2,choixJeu);
    }while(test == 0);

    // Si il y a 2 joueurs

    if(choixJeu == 2)
    {
        do
        {

            printf("\nLe deuxieme joueur doit entrer un nombre entre 1 et 100 ");
            scanf("%d", &nombreMystere);
            test(1,100,nombreMystere);
        }while (test == 0);

            system("cls");

            affichage(nombreMystere);
    }

    // S'il y a 1 joueur

    else

    {

    // Choix du niveau de difficulté

    do
    {
        printf("\nQuel niveau de difficulte voulez-vous ? (1 = facile, 2 = moyen, 3 = difficile) ");
        scanf("%d", &difficulte);
        test(1,3,difficulte);
    } while (test == 0);

    if (difficulte == 2)
        MAX = 1000;

    else if (difficulte == 3)
        MAX = 10000;

    else
        MAX = 100;

    // Génération du nombre au hasard
    srand(time(NULL));
    nombreMystere = (rand() % (MAX - MIN + 1)) + MIN;

    // Essais

       affichage(nombreMystere);

    }

    // Demande à recommencer la partie

        do
        {
            printf("\nVoulez-vous rejouer ? (1 pour oui, 0 pour non) ");
            scanf("%d", &continuerPartie);
            system("cls");
            test(0,1,continuerPartie);
        } while (test == 0);
}

return 0;

}

Affichage.c (nom pas très évocateur, je sais)
Code: [Select]
void affichage(int nombreMystere)
{
    int nombreCoups = 1, essai = 0;

    do
            {

            printf("\nQuel est le nombre ? ");
            scanf("%d", &essai);
            nombreCoups++;

            // Affichage d'incides

            if (essai < nombreMystere)
                printf("\nC'est plus grand !\n");

            else if (essai > nombreMystere)
                printf("\nC'est plus petit !\n");

            else
            {
                nombreCoups--;
                printf("\nBravo ! Vous avez trouve le nombre mystere en %d essais !\n", nombreCoups);
            }

        } while (essai != nombreMystere);
}

test.c
Code: [Select]
int test(int min, int max, int nombreEntre)
{
    if (nombreEntre < min || nombreEntre > max)
    {
        printf("\nVous n'avez pas entre un nombre correct !\n\n");
        system("PAUSE\n");

        return 0;
    }

    else
        return 1;
}

Voilà le nouveau code qui marche :

main.c :
Code: [Select]
#include
#include
#include

void affichage(int nombreMystere);

int test(int min, int max, int nombreEntre);

int main(int argc, char *argv)
{

// Écran de présentation

printf("=== Le Jeu Plus ou Moins ===\n\nCree par Emile Gregoire\n\nD'apres une idee du Site du Zer0\n\n\n");

  // Boucle pour recomencer la partie

    int continuerPartie = 1;
    while (continuerPartie)
    {

    // Initialisation des varaibles

    int MAX = 100, MIN = 1; // Nombre aléatoire
    int nombreMystere, choixJeu, difficulte, continuer;

    // Choix du mode de jeu
    do
    {
    printf("\nCombien de joueur etes-vous ? (1 ou 2) ");
    scanf("%d", &choixJeu);
    continuer = test(1,2,choixJeu);
    }while(continuer == 0);

    // Si il y a 2 joueurs

    if(choixJeu == 2)
    {
        do
        {

            printf("\nLe deuxieme joueur doit entrer un nombre entre 1 et 100 ");
            scanf("%d", &nombreMystere);
            continuer = test(1,100,nombreMystere);
        }while (continuer == 0);

            system("cls");

            affichage(nombreMystere);
    }

    // S'il y a 1 joueur

    else

    {

    // Choix du niveau de difficulté

    do
    {
        printf("\nQuel niveau de difficulte voulez-vous ? (1 = facile, 2 = moyen, 3 = difficile) ");
        scanf("%d", &difficulte);
        continuer = test(1,3,difficulte);
    } while (continuer == 0);

    if (difficulte == 2)
        MAX = 1000;

    else if (difficulte == 3)
        MAX = 10000;

    else
        MAX = 100;

    // Génération du nombre au hasard
    srand(time(NULL));
    nombreMystere = (rand() % (MAX - MIN + 1)) + MIN;

    // Essais

       affichage(nombreMystere);

    }

    // Demande à recommencer la partie

        do
        {
            printf("\nVoulez-vous rejouer ? (1 pour oui, 0 pour non) ");
            scanf("%d", &continuerPartie);
            system("cls");
            continuer = test(0,1,continuerPartie);
        } while (continuer == 0);
}

return 0;

}

Affichage.c (nom pas très évocateur, je sais)
Code: [Select]
void affichage(int nombreMystere)
{
    int nombreCoups = 1, essai = 0;

    do
            {

            printf("\nQuel est le nombre ? ");
            scanf("%d", &essai);
            nombreCoups++;

            // Affichage d'incides

            if (essai < nombreMystere)
                printf("\nC'est plus grand !\n");

            else if (essai > nombreMystere)
                printf("\nC'est plus petit !\n");

            else
            {
                nombreCoups--;
                printf("\nBravo ! Vous avez trouve le nombre mystere en %d essais !\n", nombreCoups);
            }

        } while (essai != nombreMystere);
}

test.c
Code: [Select]
int test(int min, int max, int nombreEntre)
{
    if (nombreEntre < min || nombreEntre > max)
    {
        printf("\nVous n'avez pas entre un nombre correct !\n\n");
        system("PAUSE\n");

        return 0;
    }

    else
        return 1;
}

Remarquer que j'ai éliminer la variable "int test" et créer "int continuer" et que j'ai marqué "continuer = test (x,y,z);" et que j'ai changer la condition dans ma boucle "do... while" pour mettre "continuer" au lieu de "test". J'ai fais ça à chaque fois que j'apelle la fonction "test", donc à chaque saisie de l'utilisateur.

Vous remarquerez aussi que j'ai mis très peu de commentaires sur mes modifications et mes 2 autres fonctions. C'est par lâcheté :badsmile:



Message modifié ( 16-06-2010 19:09 )

Émile

Pluton, Saturne et Jupiter
Entendez-vous monter vers vous le chant de la Terre?

- Luc Plamondon

Offline NLS le pingouin

  • Legend
  • ******
  • Posts: 826
  • Karma: 1
Reply #1 - 15 June 2010, 20:16:36
En général, quand la compilation marche pas, t'as un message de sortie qui t'indique le type d'erreur. Tu devrais peut-être nous poster ça, non?



Offline Bibi Uncle

  • Legend
  • ******
  • Posts: 2264
  • Country: Canada ca
  • Karma: 17
Reply #2 - 15 June 2010, 20:57:24
À la demande de Nico, voilà ce qu'affiche Code::Block ( ou plus précisément MingW ). Ce n'est pas le compilateur de VC++, donc, ça peut différer un peu dans le message :

Code: [Select]
mile/Mes Docum... 32 error : called object is not a function
Il ne reconnaît pas le "É" de Émile. :lol:

Et c'est le même message à chaque ligne où j'ai écrit "test(x,y,z);". (remplacer les x,y et z par les bonnes valeurs.)



Message modifié ( 15-06-2010 20:58 )

Émile

Pluton, Saturne et Jupiter
Entendez-vous monter vers vous le chant de la Terre?

- Luc Plamondon

Offline NLS le pingouin

  • Legend
  • ******
  • Posts: 826
  • Karma: 1
Reply #3 - 15 June 2010, 21:09:45
C'est quelle ligne la 32? Ya écrit quoi à cet endroit?



Offline Bibi Uncle

  • Legend
  • ******
  • Posts: 2264
  • Country: Canada ca
  • Karma: 17
Reply #4 - 15 June 2010, 21:13:03
C'est la première ligne où j'écris :

Code: [Select]
test(1,2,choixJeu);
dans la fonction main.


Émile

Pluton, Saturne et Jupiter
Entendez-vous monter vers vous le chant de la Terre?

- Luc Plamondon

Offline vinka

  • Full Member
  • ***
  • Posts: 72
  • Country: Belgium be
  • Karma: 8
Reply #5 - 15 June 2010, 23:07:27
tu as un fonction et une variable qui s'appellent toutes les deux "test"


Offline NLS le pingouin

  • Legend
  • ******
  • Posts: 826
  • Karma: 1
Reply #6 - 15 June 2010, 23:26:22
#include "test.h" ou un truc du genre? Ton fichier test.c n'est pas appelé par ton main.
D'un autre côté, t'as pas besoin de fichiers à côté de ton main, vu qu'il est tout petit...



Offline Bibi Uncle

  • Legend
  • ******
  • Posts: 2264
  • Country: Canada ca
  • Karma: 17
Reply #7 - 16 June 2010, 02:33:49
Quote
NLS le pingouin a écrit:
#include "test.h" ou un truc du genre? Ton fichier test.c n'est pas appelé par ton main.
D'un autre côté, t'as pas besoin de fichiers à côté de ton main, vu qu'il est tout petit...


Non, on n'a pas besoin d'inclure ces fichiers avec "#include". La fonction affichage n'a pas été inclu en haut et marche très bien.

J'ai séparé tout ça pour pratiquer la programation modulaire. Je sais que j'aurais très bien pu entrer tout ça dans un fichier main.c.

Quote
vinka a dit:
tu as un fonction et une variable qui s'appellent toutes les deux "test"

Je vais essayer en changeant le nom de ma variable pour voir. Par contre, je croyais que la valeur était retourné directement dans une variable du même nom, non ?


Émile

Pluton, Saturne et Jupiter
Entendez-vous monter vers vous le chant de la Terre?

- Luc Plamondon

Offline MartySpaceLines

  • Legend
  • ******
  • Posts: 1096
  • Karma: 0
Reply #8 - 16 June 2010, 10:26:45
Ah attention! Une fonction retourne un nombre (par exemple) pas une variable!
Par contre, tu peux faire prendre cette valeur à une variable!

Exemple avec une fonction "int NombreViesRestantes ()" qui retournerait le nombre de vie restantes à un personnage:

Si dans ton code tu mets seulement "NombreViesRestantes ()", cela ne sert à rien - la valeur que tu veux avoir ne sera inscrite nulle part!

Par contre, si tu mets:
Code: [Select]
int iNombreVies;

iNombreVies = NombreViesRestantes ();
Là, le nombre de vies restantes sera inscrit dans la variable "iNombreVies"!

Et bien évidemment, c'est mieux de pas mettre les même noms à tes variables et à tes fonctions...le compilateur aime pas :badsmile:

Pis juste 2 petits conseils pratiques:

 - Sur ce fofo, il existe les balises [ cpp ] et [ /cpp] (sans les espaces), qui te colorent ton code. Elles sont prévues pour le C++, mais fonctionnent aussi très bien avec du C (cf mon exemple plus haut)!

 - Lis ces tutos de Dan sur les variables et la clarté du code: ils ont totalement changé ma manière de coder!
(Une fois encore, ils sont surtout prévus pour du C++, mais bien adaptables au C!)

http://orbiter.dansteph.com/forum/index.php?topic=6344.msg95487#msg95487

http://orbiter.dansteph.com/forum/index.php?topic=6359.msg95780#msg95780


@++

MSL  


Offline NLS le pingouin

  • Legend
  • ******
  • Posts: 826
  • Karma: 1
Reply #9 - 16 June 2010, 13:16:44
Quote
Bibi Uncle a écrit:
Quote
NLS le pingouin a écrit:
#include &quot;test.h&quot; ou un truc du genre? Ton fichier test.c n'est pas appelé par ton main.
D'un autre côté, t'as pas besoin de fichiers à côté de ton main, vu qu'il est tout petit...


Non, on n'a pas besoin d'inclure ces fichiers avec "#include". La fonction affichage n'a pas été inclu en haut et marche très bien.
Ah oui, t'as sans doute raison.. J'ai plus l'habitude du c++.

Bon, clairement, ton soucis c'est qu'il reconnait pas test comme une fonction. J'ai pas lu tout le code, mais ce problème revient souvent.
Soit t'as deux éléments qu'on le même nom.
Soit t'as déclaré, mais pas défini ta fonction (ou inversement). C'est des cas classiques.

Mais je me souviens plus assez des mécanismes du C pour pouvoir t'aider plus loin...



Offline Bibi Uncle

  • Legend
  • ******
  • Posts: 2264
  • Country: Canada ca
  • Karma: 17
Reply #10 - 16 June 2010, 19:05:57
Quote
MartySpaceLines a écrit:
Ah attention! Une fonction retourne un nombre (par exemple) pas une variable!
Par contre, tu peux faire prendre cette valeur à une variable!

Exemple avec une fonction "int NombreViesRestantes ()" qui retournerait le nombre de vie restantes à un personnage:

Si dans ton code tu mets seulement "NombreViesRestantes ()", cela ne sert à rien - la valeur que tu veux avoir ne sera inscrite nulle part!

Par contre, si tu mets:
Code: [Select]
int iNombreVies;

iNombreVies = NombreViesRestantes ();
Là, le nombre de vies restantes sera inscrit dans la variable "iNombreVies"!

Et bien évidemment, c'est mieux de pas mettre les même noms à tes variables et à tes fonctions...le compilateur aime pas :badsmile:

Pis juste 2 petits conseils pratiques:

 - Sur ce fofo, il existe les balises [ cpp ] et [ /cpp] (sans les espaces), qui te colorent ton code. Elles sont prévues pour le C++, mais fonctionnent aussi très bien avec du C (cf mon exemple plus haut)!

 - Lis ces tutos de Dan sur les variables et la clarté du code: ils ont totalement changé ma manière de coder!
(Une fois encore, ils sont surtout prévus pour du C++, mais bien adaptables au C!)

http://orbiter.dansteph.com/forum/index.php?topic=6344.msg95487#msg95487

http://orbiter.dansteph.com/forum/index.php?topic=6359.msg95780#msg95780


D'accord ! Là je comprend. Par contre, si j'avait marqué ceci :

Code: [Select]
do
    {
    printf("\nCombien de joueur etes-vous ? (1 ou 2) ");
    scanf("%d", &choixJeu);
    }while(test(1,2,choixJeu) == 0);

Est-ce que ça aurait marché ?

Pour les tutos, j'ai feuilleté tous ceux disponibles dans le lien sur le forum sur la création. J'ai voulu installé VC++ 2005 mais Microsoft est rendu à la version 2008 (et maintenant 2010 je crois) et il faut envoyer une clé (même la version Express). Je trouve ça un peu bizarre...

P.S. Merci pour l'astuce des balise. ;) J'ai modifier mon premier message avec cette astuce.



Message modifié ( 16-06-2010 19:10 )

« Last Edit: 16 June 2010, 21:26:18 by Bibi Uncle »
Émile

Pluton, Saturne et Jupiter
Entendez-vous monter vers vous le chant de la Terre?

- Luc Plamondon

Offline NLS le pingouin

  • Legend
  • ******
  • Posts: 826
  • Karma: 1
Reply #11 - 16 June 2010, 20:16:19
Normalement, aucun problème.
Tu aurais même pu faire :
Code: [Select]
do
    {
    printf("\nCombien de joueur etes-vous ? (1 ou 2) ");
    scanf("%d", &choixJeu);
    }while(!test(1,2,choixJeu));

C'est juste un détail, mais une fois que tu l'as assimilé, ça clarifie pas mal ton code. Si tu voulais faire :
Code: [Select]
while(test(1,2,choixjeu) == 1);Tu aurais fais :
Code: [Select]
while(test(1,2,choixjeu));
//Dans ce cas, la boucle continue tant que test(... ... ...) != 0
C'est assez interressant quand t'as un plus grand nombre de fonction. Au moins, tu sais que ta fonction retourne un booléen (0 ou 1, true ou false). Ca permet une lecture rapide et un meilleure différentiation des fonctions.


« Last Edit: 16 June 2010, 21:26:18 by NLS le pingouin »

Offline MartySpaceLines

  • Legend
  • ******
  • Posts: 1096
  • Karma: 0
Reply #12 - 16 June 2010, 20:31:14
Pas de souci ;) je suis content de pouvoir retransmettre ces astuces, après les avoir moi-même reçues de pontes du forum (Dan, No Matter etc...)

Juste un truc que je ne comprend pas (c'est pas une critique, juste une question): Pourquoi ta fonction "test" met-elle la PAUSE? Il me semble que le scanf fais déjà attendre le programme d'obtenir une entrée... :wonder:

@NLS: Tiens, je savais pas qu'on pouvait "simuler" des bool en C! :)


« Last Edit: 16 June 2010, 21:26:18 by MartySpaceLines »
@++

MSL  


Offline Bibi Uncle

  • Legend
  • ******
  • Posts: 2264
  • Country: Canada ca
  • Karma: 17
Reply #13 - 16 June 2010, 21:00:09
Parce que d'habitude, quand une fonction n'est fait qu'un printf, je met un system(PAUSE); pour pouvoir laisser le temps à l'utilisateur de voir le texte. Par contre, c'est vrai que là, ça ne sert à rien parce que la boucle va redemander une saisie.

Merci pour cette remarque, une correction de mon code.

Pour Nico, tu me rappelles une leçon du Site du Zér0. j'avais carrémenent oublier ça. Et hop, une autre correction à faire. Après tout, c'était le but de ce fil. Apprendre encore plus le C pour pouvoir m'améliorer. J'ai hâte d'être en C++ pour avoir les booléens. Ça simplifie beaucoup le code.


« Last Edit: 16 June 2010, 21:26:18 by Bibi Uncle »
Émile

Pluton, Saturne et Jupiter
Entendez-vous monter vers vous le chant de la Terre?

- Luc Plamondon

Offline NLS le pingouin

  • Legend
  • ******
  • Posts: 826
  • Karma: 1
Reply #14 - 16 June 2010, 21:26:18
Wé! L'orienté objet, c'est la vie! Je peux plus m'en passer!


« Last Edit: 16 June 2010, 21:26:18 by NLS le pingouin »