Questions d'un débutant en C... - C - Programmation
Marsh Posté le 30-03-2006 à 14:58:50
L'expression c = getchar() != EOF; est évaluée comme c = (getchar() != EOF );
Deux cas possibles
Pour ton programme
Code :
|
Pense que le prototype de main est soit
La fonction main retourne un entier, soit 0, soit EXIT_SUCCESS soit EXIT_FAILURE
Marsh Posté le 30-03-2006 à 15:00:43
Citation :
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. |
A cause de la priorité des opérateurs,
Code :
|
est équivalent à
Code :
|
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. |
Je pense que ce qu'ils attendent de toi ici est tout simplement un truc du genre :
Code :
|
Citation : Exercice 1-7. Ecrivez un programme qui affiche la valeur de EOF. |
tu n'as pas mis la bonne signature pour main. Voici une version conforme à la norme:
Code :
|
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 :
|
et il t'affichera -1.000.
Marsh Posté le 30-03-2006 à 15:06:03
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.
Marsh Posté le 30-03-2006 à 15:28:47
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
Marsh Posté le 30-03-2006 à 16:22:49
Ok merci beaucoup, je comprends déjà mieu...
Donc, si j'ai bien compris
Code :
|
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 :
|
et non pas
Code :
|
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 |
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
Marsh Posté le 30-03-2006 à 16:32:30
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
Marsh Posté le 30-03-2006 à 16:33:43
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.
Marsh Posté le 30-03-2006 à 16:38:26
Ok, merci.
Et, donc, comment faire pour que
Code :
|
=0
?
Car, avec ce programme :
Code :
|
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..
Marsh Posté le 30-03-2006 à 16:57:23
ReplyMarsh Posté le 30-03-2006 à 17:03:03
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
or with two parameters (referred to here as argc and argv, though any names may be
|
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.
Marsh Posté le 30-03-2006 à 17:07:54
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.
Marsh Posté le 30-03-2006 à 17:11:28
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
et non pas
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
Marsh Posté le 30-03-2006 à 17:13:03
franceso a écrit : 2-3) voici un extrait de la norme C90 (ISO/IEC 9899:1999) |
Si c'est xxx:1999, c'est C99 !
Marsh Posté le 30-03-2006 à 17:17:32
Emmanuel Delahaye a écrit : Un entier valant 0 ou 1 est très exactement un type booleen. |
C'est un type au sens C ?
Marsh Posté le 30-03-2006 à 17:24:49
Trap D a écrit : C'est un type au sens C ? |
C, non, mais au sens général, oui.
Marsh Posté le 30-03-2006 à 17:25:39
Trap D a écrit : Crtl D sous MicroSoft / DOS je crois. |
Ctrl-Z
Marsh Posté le 30-03-2006 à 18:05:06
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 ...
Marsh Posté le 30-03-2006 à 18:13:46
ReplyMarsh Posté le 31-03-2006 à 13:50:22
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 :
|
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?
Marsh Posté le 31-03-2006 à 13:55:40
il ne faudrait pas encadrer tes "if" dans le "while" ? (utilisation de { })
Marsh Posté le 31-03-2006 à 16:28:49
Encore un petit problème :
Ecrivez un programme qui affiche son entrée à raison d'un mot par ligne.
J'ai créé celà :
Code :
|
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...
Marsh Posté le 31-03-2006 à 16:40:28
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 :
|
Marsh Posté le 31-03-2006 à 16:42:49
personnellement, j'aurais structuré ça un peu différemment :
Code :
|
ça évite de tester deux fois si c est un espace, une tabulation ou un retour à la ligne.
Marsh Posté le 31-03-2006 à 16:44:19
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...
Marsh Posté le 31-03-2006 à 16:48:28
on peut faire nettement plus concis
Code :
|
Marsh Posté le 31-03-2006 à 16:52:27
Oui, mais je crois que Floboss07 voulait éviter les retours à la ligne multiples lorsqu'il y a plusieurs espaces à la suite.
Marsh Posté le 30-03-2006 à 14:02:56
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
n'est pas pareil que
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 :
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