Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1670 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Questions d'un débutant en C...

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Questions d'un débutant en C...

n°1335517
floboss07
Posté le 30-03-2006 à 14:02:56  profilanswer
 

Alors voilà, je me suis maintenant bien attaqué au livre "Le langage C, norme ANSI, 2eme edition" de K&R...
J'en suis au début encore...
Et, dans cette édition, il y a des exercices à la fin de chaque sous chapitre, mais les corrections sont dans un autre livre (que je n'ai pas).
Donc, jen suis à l'exercice 1-6 et 1-7.
Je vous explique:
Il est dit précédemment que, dans un while

Code :
  1. (c = getchar()) != EOF)


n'est pas pareil que

Code :
  1. c = getchar() != EOF


 
Car dans le 2eme cas, la priorité est au !=, donc le test de relation != serait effectué avant l'affectation =. Ca, c'est bon, j'ai compris.
Mais c'est la suite où j'ai un peu du mal...
En effet, il est écrit que cette instruction a l'effet indésirable de mettre c à 0 ou à 1, selon que l'appel getchar a rencontré la fin de fichier ou pas.
Alors là déjà je ne comprends pas trop le sens... Si vous pouviez m'expliquer...  :)  
 
Et après, l'exercice, c'est de :
Exercice 1-6. Vérifiez que l'expression getchar() !=EOF vaut soit 0, soit 1.
J'ai pensé pour celà à utilisé un if (malgrès qu'il n'a pas encore été abordé jusqu'ici dans le livre), mais je ne sais pas trop comment le faire en fait. Pour info, à cet endroit du livre, seuls les while et for ont été abordés comme "opérations" (je ne sais pas si le therme est le bon), donc à mon avis il doit y avoir un moyen en utilisant un while ou for...
 
L'autre exercice est:
Exercice 1-7. Ecrivez un programme qui affiche la valeur de EOF.
J'ai essayé cela, et j'ai fini par faire ce programme :

Code :
  1. #include <stdio.h>
  2. main()
  3. {
  4.     int mini;
  5.     mini = EOF;
  6.     printf("%d", mini);
  7. }


Et ça m'affiche -1.
Sauf que, quand je remplace le %d par un %f, ça m'affiche 0 !
Comment cela se fait-il?
 
Voilà, merci :)
 
 
P.S. Pour les autres questions tout au long de ma lecture de ce livre, préférez-vous que je les pause à la suite de ce post ou que je cré des nouveaux posts?


Message édité par floboss07 le 30-03-2006 à 14:03:39
mood
Publicité
Posté le 30-03-2006 à 14:02:56  profilanswer
 

n°1335563
Trap D
Posté le 30-03-2006 à 14:58:50  profilanswer
 

L'expression c = getchar() != EOF; est évaluée comme c = (getchar() != EOF );
 
Deux cas possibles

  • getchar() renvoie EOF en fin de fichier, le test getchar() != EOF est faux et donc renvoie 0.
  • getchar() renvoie une valeur différente de EOF, le test getchar() != EOF réussit et renvoie donc 1.

Pour ton programme

Code :
  1. #include <stdio.h>
  2. main()
  3. {
  4.     int mini;
  5.     mini = EOF;
  6.     printf(&#034;%d", mini);
  7. }

Pense que le prototype de main est soit

  • int main(void) si tu n'as pas besoin des arguments de la ligne de commande
  • int main (int argc, char **argv) si tu en as besoin.


La fonction main retourne un entier, soit 0, soit EXIT_SUCCESS soit EXIT_FAILURE


Message édité par Trap D le 30-03-2006 à 15:03:33
n°1335566
franceso
Posté le 30-03-2006 à 15:00:43  profilanswer
 

Citation :

Code :
  1. c = getchar() != EOF

cette instruction a l'effet indésirable de mettre c à 0 ou à 1, selon que l'appel getchar a rencontré la fin de fichier ou pas.
Alors là déjà je ne comprends pas trop le sens... Si vous pouviez m'expliquer...  :)

A cause de la priorité des opérateurs,

Code :
  1. c = getchar() != EOF

est équivalent à

Code :
  1. c = (getchar() != EOF)

Le problème, c'est que l'évaluation de l'expression getchar() != EOF renvoie une valeur booléenne qui est tranformée en 0 ou 1 lorsque tu demandes de la stocker dans la variable entière c
 
 

Citation :

Exercice 1-6. Vérifiez que l'expression getchar() !=EOF vaut soit 0, soit 1.
J'ai pensé pour celà à utilisé un if (malgrès qu'il n'a pas encore été abordé jusqu'ici dans le livre), mais je ne sais pas trop comment le faire en fait. Pour info, à cet endroit du livre, seuls les while et for ont été abordés comme "opérations" (je ne sais pas si le therme est le bon), donc à mon avis il doit y avoir un moyen en utilisant un while ou for...

Je pense que ce qu'ils attendent de toi ici est tout simplement un truc du genre :

Code :
  1. int i = (getchar() != EOF);
  2. printf( "%d\n", i );


 
 

Citation :

Exercice 1-7. Ecrivez un programme qui affiche la valeur de EOF.
J'ai essayé cela, et j'ai fini par faire ce programme : ...

tu n'as pas mis la bonne signature pour main. Voici une version conforme à la norme:

Code :
  1. #include <stdio.h>
  2. int main() /* main() renvoie toujours un int */
  3. {
  4.   int mini;
  5.   mini = EOF;
  6.   printf("%d\n", mini);
  7.   return 0;
  8. }


 
 

Citation :

Sauf que, quand je remplace le %d par un %f, ça m'affiche 0 !

tu demandes d'afficher un float (%f) mais tu fournis à printf un argument de type int ! Pas étonnant qu'il fasse n'importe quoi. Normalement, ton compilateur a du te mettre un warning à cette ligne (si ce n'est pas le cas, tu devrais lui passer des options pour qu'il te donne plus de warnings).
Si tu veux, à la limite, tu peux faire

Code :
  1. printf( "%f\n", (double)mini );

et il t'affichera -1.000.


Message édité par franceso le 30-03-2006 à 15:01:18

---------------
TriScale innov
n°1335573
Trap D
Posté le 30-03-2006 à 15:06:03  profilanswer
 

En C, l' évaluation de getchar() != EOF ne renvoie pas une valeur booléenne mais un entier 0 ou 1.  
En C tout ce qui n'est pas 0 est considéré comme vrai.

n°1335600
franceso
Posté le 30-03-2006 à 15:28:47  profilanswer
 

Trap D a écrit :

En C, l' évaluation de getchar() != EOF ne renvoie pas une valeur booléenne mais un entier 0 ou 1.

OK, mes excuses : en C, le type booléen n'existe pas :jap:


---------------
TriScale innov
n°1335656
floboss07
Posté le 30-03-2006 à 16:22:49  profilanswer
 

Ok merci beaucoup, je comprends déjà mieu...
Donc, si j'ai bien compris

Code :
  1. c = (getchar() != EOF)

donne à c la valeur 1 si getchar() est différent de EOF, et 0 si il est égal à EOF? (1)
Mais par contre, pour la "signature du main", je ne comprends pas ce que tu veux dire franceso... Dans mon livre, les programmes commencent toujours par

Code :
  1. main()

et non pas

Code :
  1. int main()

et ce livre respecte la norme ANSI...("le langage C, norme ANSI, 2e edition" )(2)
Et idem pour trap D, je ne comprend pas ce que tu veux dire quand tu dis

Citation :

Pense que le prototype de main est soit
 
    * int main(void) si tu n'as pas besoin des arguments de la ligne de commande
    * int main (int argc, char **argv) si tu en as besoin.  
 
 
La fonction main retourne un entier, soit 0, soit EXIT_SUCCESS soit EXIT_FAILURE


Car à vrai dire, là où j'en suis je n'ai pas encore vu de int main(void) ou autre (pour l'instant, la parenthèse était toujours vide (3), et d'ailleur, il n'y avait pas de int comme je l'ai dit précédemment).
Et en conclusion, je ne comprend donc pas pourquoi il m'affiche -1 en valeur de EOF... en fait, à quoi correspond EOF? Ce n'est pas censé représenté 0 justement?(4)
 
 
EDIT : J'ai numéroté chaque question distincte pour que ça soit un peu plus clair  :bounce:

Message cité 1 fois
Message édité par floboss07 le 30-03-2006 à 16:27:15
n°1335661
skelter
Posté le 30-03-2006 à 16:32:30  profilanswer
 

4) EOF ne peut pas etre dans le rang d'un char (sinon comment savoir si getchar renvoi EOF ou un caractere lu sur stdout), et 0 est un caractere valide ('\0', caractere nul)
par contre l'entier -1 est hors du rang d'un char si un int est codé en 32bits + complément à deux pour les nombres négatifs: (unsigned int)(-1) == UINT_MAX > UCHAR_MAX

n°1335663
Trap D
Posté le 30-03-2006 à 16:33:43  profilanswer
 

EOF est une valeur réservée spéciale ayant la valeur -1. Cette valeur ne peut pas être confondue avec n'importe quel caractère pouvant être lu dans un fichier.
C'est pourquoi il est impératif que c soit un int, car avec un char, il pourrait y avoir confusion avec EOF.
Le livre de K&R est une référence c'est vrai mais qui date un peu, donc il faut se mettre à jour et utiliser la norme actuelle qui impose les prototype de main.

n°1335668
floboss07
Posté le 30-03-2006 à 16:38:26  profilanswer
 

Ok, merci.
Et, donc, comment faire pour que

Code :
  1. (getchar() != EOF)


=0
?
Car, avec ce programme :

Code :
  1. #include <stdio.h>
  2. main()
  3. {
  4.     int mini;
  5.     mini = (getchar() != EOF);
  6.     printf("%d", mini);
  7. }


Quelle que soit la touche sur laquelle j'appui, il m'affiche toujours 1... Pourtant je pensé qu'en entrant aucun caractère, juste en appuyant sur la touche entrée, ça mettrais 0..Mais en fait non.
 
EDIT : En clair, j'ai compris que getchar() = EOF est "l'indicateur de fin de fichier", mais je ne comprends pas à quoi ça correspond par rapport au clavié.. Enfin qu'est ce qu'il faut faire pour l'obtenir quoi..


Message édité par floboss07 le 30-03-2006 à 16:41:41
n°1335679
Trap D
Posté le 30-03-2006 à 16:57:23  profilanswer
 

Crtl D sous MicroSoft / DOS je crois.

mood
Publicité
Posté le 30-03-2006 à 16:57:23  profilanswer
 

n°1335682
franceso
Posté le 30-03-2006 à 17:03:03  profilanswer
 

2-3)  voici un extrait de la norme C90 (ISO/IEC 9899:1999)

Citation :

The function called at program startup is named main. The implementation declares no
prototype for this function. It shall be defined with a return type of int and with no
parameters:

Code :
  1. int main(void) { /* ... */ }

or with two parameters (referred to here as argc and argv, though any names may be
used, as they are local to the function in which they are declared):

Code :
  1. int main(int argc, char *argv[]) { /* ... */ }



le type de retour de la fonction main est toujours un entier. Il s'agit d'une valeur qui est renvoyée par ton programme au système d'exploitation. Les valeurs normalisées sont 0 (succès), EXIT_SUCCESS (succès) et EXIT_FAILURE (echec).
 
Si tu ne définis pas de type de retour pour ta fonction main, on suppose par défaut que c'est un int (et c'est pour ça que les exemples du livre sont quand même valides)
 
Si tu déclares ta fonction main avec deux arguments (par ex: int main(int argc, char**argv)) alors argv[0] ... argv[argc-1] sont des pointeurs vers des chaines de caractères contenant les jetons de la ligne de commande utilisée pour lancer le programme. Donc argv[0] contient le nom du programme, et argv[1] ... argv[argc-1] contiennent les arguments fournis au programme sur la ligne de commande.


---------------
TriScale innov
n°1335685
Emmanuel D​elahaye
C is a sharp tool
Posté le 30-03-2006 à 17:07:54  profilanswer
 

Trap D a écrit :

En C, l' évaluation de getchar() != EOF ne renvoie pas une valeur booléenne mais un entier 0 ou 1.


Un entier valant 0 ou 1 est très exactement un type booleen.
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1335688
Emmanuel D​elahaye
C is a sharp tool
Posté le 30-03-2006 à 17:11:28  profilanswer
 

floboss07 a écrit :

Mais par contre, pour la "signature du main", je ne comprends pas ce que tu veux dire franceso... Dans mon livre, les programmes commencent toujours par

Code :
  1. main()

et non pas

Code :
  1. int main()

et ce livre respecte la norme ANSI...("le langage C, norme ANSI, 2e edition" )(2)


Ce livre est sorti juste avant la publication de la norme et s'appuyait sur les brouillons (drafts) de l'époque. Il y a eu des corrections plus tard :  
 
http://mapage.noos.fr/emdel/init_c.htm
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1335690
Emmanuel D​elahaye
C is a sharp tool
Posté le 30-03-2006 à 17:13:03  profilanswer
 

franceso a écrit :

2-3)  voici un extrait de la norme C90 (ISO/IEC 9899:1999)


Si c'est xxx:1999, c'est C99 !

Message cité 1 fois
Message édité par Emmanuel Delahaye le 30-03-2006 à 17:14:29

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1335694
Trap D
Posté le 30-03-2006 à 17:17:32  profilanswer
 

Emmanuel Delahaye a écrit :

Un entier valant 0 ou 1 est très exactement un type booleen.


C'est un type au sens C ?

n°1335700
Emmanuel D​elahaye
C is a sharp tool
Posté le 30-03-2006 à 17:24:49  profilanswer
 

Trap D a écrit :

C'est un type au sens C ?


C, non, mais au sens général, oui.
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1335701
Emmanuel D​elahaye
C is a sharp tool
Posté le 30-03-2006 à 17:25:39  profilanswer
 

Trap D a écrit :

Crtl D sous MicroSoft / DOS je crois.


Ctrl-Z


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1335737
Trap D
Posté le 30-03-2006 à 18:05:06  profilanswer
 

Emmanuel Delahaye a écrit :

C, non, mais au sens général, oui.


On est bien d'accord  :)  
 
OK pour le Crtl Z, comme je ne peux pas tester actuellement ... :whistle:

n°1335747
franceso
Posté le 30-03-2006 à 18:13:46  profilanswer
 

Emmanuel Delahaye a écrit :

Si c'est xxx:1999, c'est C99 !

:sweat: Oups, mon clavier a fourché!!!

n°1336315
floboss07
Posté le 31-03-2006 à 13:50:22  profilanswer
 

Bon, nouvelle question, mais j'vais rester sur le même sujet pour pas trop foutre le bordel lol...
 
La question cette fois c'est :
2crivez un programme qui compte les espaces, les tabulations et les fins de ligne.
 
J'ai donc créé celà (en me servant des exemple précédents du livre) :
 

Code :
  1. #include <stdio.h>
  2. int main(void)
  3. {
  4.     int c, nl, nt, ne;
  5.     nl = 0;
  6.     nt = 0;
  7.     ne = 0;
  8.     while ((c = getchar()) != EOF)
  9.         if (c == '\n')
  10.             ++nl;
  11.         if (c == ' ')
  12.             ++ne;
  13.         if (c == '\t')
  14.             ++nt;
  15.         printf("Il y a" );
  16.         printf("%d", nl);
  17.         printf(" lignes, " );
  18.         printf("%d", nt);
  19.         printf("tabulation, et" );
  20.         printf("%d", ne);
  21.         printf(" espaces." );
  22. }


 
Mais, quoi que je fasse, ça me met toujours le bon nombre de lignes, mais 0 espaces et 0 tabulations...
Où ais-je fait une erreur?

n°1336319
jlighty
Posté le 31-03-2006 à 13:55:40  profilanswer
 

il ne faudrait pas encadrer tes "if" dans le "while" ? (utilisation de { })


Message édité par jlighty le 31-03-2006 à 13:55:58
n°1336324
floboss07
Posté le 31-03-2006 à 14:06:38  profilanswer
 

Merci, oui, c'était juste ça, erreur toute conne! :)

n°1336483
floboss07
Posté le 31-03-2006 à 16:28:49  profilanswer
 

Encore un petit problème :
Ecrivez un programme qui affiche son entrée à raison d'un mot par ligne.
 
J'ai créé celà :

Code :
  1. #include <stdio.h>
  2. int main(void)
  3. {
  4.     int c, statut;
  5.     c = statut = 0;
  6.     while ((c = getchar()) != EOF){
  7.     if (c != ' ' || c != '\t' || c != '\n'){
  8.     statut = 1;
  9.     putchar(c);
  10. }
  11.     if (statut != 0 && (c == ' ' || c == '\t' || c == '\n')){
  12.     statut = 0;
  13.     putchar('\n');}
  14.     }
  15.   return 0;
  16. }


 
Sauf que, malgrès que j'ai mis un "statu" afin qu'une foi qu'il a sauté une ligne il n'en saute plus, si je met plusieurs espaces à la suite il saute plusieurs lignes. Comment cela se fait-il? J'ai surement du encore faire une petite erreur toute conne je suppose...


Message édité par floboss07 le 31-03-2006 à 16:29:21
n°1336493
franceso
Posté le 31-03-2006 à 16:40:28  profilanswer
 

tu veux que la condition soit vraie uniquement dans le cas où c n'est ni ' ', ni '\t', ni '\n' => il faut mettre des 'et' (&& ) à la place des 'ou' (||) :  

Code :
  1. if (c != ' ' && c != '\t' && c != '\n')


---------------
TriScale innov
n°1336496
franceso
Posté le 31-03-2006 à 16:42:49  profilanswer
 

personnellement, j'aurais structuré ça un peu différemment :

Code :
  1. #include <stdio.h>
  2. int main(void)
  3. {
  4.   int c, statut;
  5.   c = statut = 0;
  6.   while ((c = getchar()) != EOF){
  7.     if (c != ' ' && c != '\t' && c != '\n')
  8.       {
  9.         statut = 1;
  10.         putchar(c);
  11.       }
  12.     else if (statut != 0)
  13.       {
  14.         statut = 0;
  15.         putchar('\n');
  16.       }
  17.   }
  18.  
  19.   return 0;
  20. }


 
ça évite de tester deux fois si c est un espace, une tabulation ou un retour à la ligne.


---------------
TriScale innov
n°1336498
floboss07
Posté le 31-03-2006 à 16:44:19  profilanswer
 

Lol, vraiment merci, comme je pensais c'était encore une petite erreur toute conne...
Peut-être qu'avec l'habitude j'arrêterais d'en faire...

n°1336505
skelter
Posté le 31-03-2006 à 16:48:28  profilanswer
 

on peut faire nettement plus concis
 

Code :
  1. #include <stdio.h>
  2. #include <ctype.h>
  3. int main()
  4. {
  5.     int c;
  6.    
  7.     while( (c = getchar()) != EOF )
  8.     {
  9.         if( isspace(c) )
  10.             c = '\n';
  11.        
  12.         putchar(c);
  13.     }
  14.    
  15.     return 0;
  16. }

n°1336509
franceso
Posté le 31-03-2006 à 16:52:27  profilanswer
 

Oui, mais je crois que Floboss07 voulait éviter les retours à la ligne multiples lorsqu'il y a plusieurs espaces à la suite.


---------------
TriScale innov
n°1336512
skelter
Posté le 31-03-2006 à 16:55:01  profilanswer
 

ha oui, ok

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Questions d'un débutant en C...

 

Sujets relatifs
[Résolu] [Batch] [Newbies] Diverses questions au sujet du Batch"débutant" sous excel ...
debutant: gestion de la mémoireaide débutant en python
probleme de debutant[Débutant] [VB.NET] Insertion image à partir d'une datagridv
Petit soucis d'un débutant ...[débutant] Est ce que c'est faisable ?
[Debutant] Heritage et appel de fonctionAide débutant rêgle REGEXP
Plus de sujets relatifs à : Questions d'un débutant en C...


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR