Bonjour,
je débute en C. Je lis le K&R. À la page 75, on implémente une calculatrice basique. Il y a des choses qui m'échappent.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAXOP 100 /* taille maximale d'un opérande ou d'un opérateur */
#define NOMBRE '0' /* indique que l'on a lu un nombre */
int lire_op(char []);
void empiler(double);
double depiler(void);
/* calculatrice en polonaise inversée */
int main()
{
int type;
double op2;
char s[MAXOP];
while ((type = lire_op(s)) != EOF) {
switch(type) {
case NOMBRE:
empiler(atof(s));
break;
case '+':
empiler(depiler() + depiler());
break;
case '*':
empiler(depiler() * depiler());
break;
case '-':
op2 = depiler();
empiler(depiler() - op2);
break;
case '/':
op2 = depiler();
if (op2 != 0.0)
empiler(depiler() / op2);
else
printf("erreur : division par zéro\n");
break;
case '\n':
printf("\t%.8g\n", depiler());
break;
default:
printf("erreur : commande inconnue %s\n", s);
break;
}
}
return 0;
}
#define MAXVAL 100 /* profondeur maxi de la pile val */
int pp = 0; /* prochaine position libre de la pile */
double val[MAXVAL]; /* pile de valeurs */
/* empiler : place f au sommet de la pile de valeurs */
void empiler(double f)
{
if (pp < MAXVAL)
val[pp++] = f;
else
printf("pile pleine, impossible d'empiler %g\n", f);
}
/* depiler : extrait et retourne la valeur du sommet de la pile */
double depiler(void)
{
if (pp > 0)
return val[--pp];
else {
printf("erreur : pile vide\n");
return 0.0;
}
}
int lirecar(void);
void remettrecar(int);
/* lire_op : lit le prochain opérateur ou opérande numérique */
int lire_op(char s[])
{
int i, c;
while ((s[0] = c = lirecar()) == ' ' || c == '\t')
;
s[1] = '\0';
if (!isdigit(c) && c != '.')
return c; /* pas un nombre */
i = 0;
if (isdigit(c)) /* lire la partie entière */
while (isdigit(s[++i] = c = lirecar()))
;
if (c == '.') /* lire la partie fractionnaire */
while (isdigit(s[++i] = c = lirecar()))
;
s[i] = '\0';
if (c != EOF)
remettrecar(c);
return NOMBRE;
}
#define TAILLETAMP 100
char tamp[TAILLETAMP]; /* tampon pour remettrecar */
int ptamp = 0; /* prochaine position libre dans tamp */
int lirecar(void) /* lit un caractère (éventuellement remis sur l'entrée) */
{
return (ptamp > 0) ? tamp[--ptamp] : getchar();
}
void remettrecar(int c) /* remet c sur l'entrée */
{
if (ptamp >= TAILLETAMP)
printf("remettrecar : trop de caractères\n");
else
tamp[ptamp++] = c;
} |
Lorsque je tape CTRL+D (je suis sur Mac), la fonction lire_op renvoie -1 et on quitte la boucle while. En revanche, si je tape a (par exemple) suivi de CTRL+D, le terminal affiche
erreur : commande inconnue a
, mais en revanche on ne quitte pas la boucle while juste après (ce que je ne comprends pas).
Par avance merci pour vos explications.
Partager