4 FUNKCJE I STRUKTURA PROGRAMU
Funkcja main jest pętlą zawierającą ogromną instrukcję switch, która z kolei steruje działaniem kalkulatora zgodnie z typem operatora lub argumentu. Być może jest to bardziej typowe zastosowanie instrukcji switch niż przedstawione w p. 3.4.
#include <stdio.h>
#include <stdlib.h> /* dla atof() */
#define MAXOP 100 /* max. długość operandu lub operatora */
#define NUMBER ’0’ /* sygnał znalezienia liczby */
int getop(char [ ]); void push(double); double pop(void);
/* kalkulator wg Odwrotnej Notacji Polskiej */ main()
int type; double op2; char s[MAXOP];
while ((type = getop(s)) != EOF) { switch (type) { case NUMBER: push(atof(s)); break; case
push(pop() + pop()); break; case V:
push(pop() * pop()); break; case
op2 = pop(); push(pop() - op2); break; case
op2 = pop(); if (op2 != 0.0)
push(pop() / op2); else
printf(”błąd: dzielenie przez 0\n”); break;
4.3 ZMIENNE ZEWNĘTRZNE ________
powerpd_by
Mi siol
case ’\n’:
printf(”\t%.8g\n”, pop()); break; default:
printf(”błąd: nieznane polecenie %s\n”, s); break;
return 0;
Operatory dodawania + i mnożenia * są przemienne, kolejność pobierania ich argumentów nie jest więc istotna. Należy natomiast rozróżnić argumenty lewy i prawy dla operatorów odejmowania - i dzielenia /. W instrukcji
push(pop() - pop()); I* ŹLE */
kolejność, w jakiej wywołuje się obie funkcje pop, nie jest określona. Aby zapewnić poprawną kolejność obliczeń, należy najpierw wartość ze szczytu stosu pobrać do zmiennej tymczasowej, tak jak to zrobiliśmy w main.
#define MAXVAL 100 /* maks. głębokość stosu */
int sp = 0; /* następne wolne miejsce na stosie */
double val[MAXVAL] /* stos wartości */
I* push: wstaw f na stos */ void push(double f)
if (sp < MAXVAL) val[sp-H-] = f; else
printffbłąd; pełen stos; nie można umieścić %g\n”, f);
I* pop: zdejmij i zwróć wartość ze szczytu stosu */ double pop(void)
if (sp > 0)
return val[—sp]; else {
printffbłąd: pusty stos\n”); return 0.0;
ni