Implementierung eines UPN-Rechners für Brüche:
Beispiel:
1 8 / 5 8 / + 1 - = -1/4 6 2 3 / * = 4
Programmstruktur
// fstack.h: a simple stack #include "fract.h" // class fraction void push(fraction val); // Deklaration fraction pop(void); // Deklaration
! Zeilenkommentar //.
! Funktionsprototypen
// fstack.cc: a simple stack #include <iostream.h> #include "fract.h" #include "fstack.h" const int STACKSIZE = 20; fraction stack[STACKSIZE]; int stackptr = 0; void push(fraction val) { if (stackptr <= STACKSIZE - 1) stack[stackptr++] = val; else cerr << "Stack Overflow.\n"; } /* push */ fraction pop() { if (stackptr > 0) stackptr--; else cerr << "Stack Underflow.\n"; return stack[stackptr]; } /* pop */
! Konstanten statt #define.
! Benutzung von iostream.
// fract.h: class "fraction" #ifndef _FRACT_H #define _FRACT_H #include <iostream.h> class fraction { int fnum; int fden; public: int num() {return fnum;} // access fnum int den() {return fden;} // access fden void print() // output { if (fden != 1) cout << fnum << '/' << fden << "\n"; else cout << fnum << "\n"; } /* print */ fraction(int n = 0, int d = 1) // constructor { fnum = n; fden = d; } /* fraction */ }; // operators: fraction operator + (fraction a, fraction b); fraction operator - (fraction a, fraction b); fraction operator * (fraction a, fraction b); fraction operator / (fraction a, fraction b); #endif
! Klasse mit ``private'' und ``public'' Komponenten.
! Element-Funktionen.
! Konstruktoren.
! Default-Parameter.
! Definition überladener Operatoren.
! Schutz vor Mehrfach-Inklusion.
// fract.cc: Fraction Operations #include "fract.h" int gcd(int a, int b) { if (a < 0) return gcd(-a, b); if (a == 0) return b; if (b < a) return gcd(b, a); return gcd(b % a, a); } /* gcd */ fraction reduce(fraction f) { fraction r; int g = gcd(f.num(), f.den()); if (g != 0) r = fraction(f.num()/g, f.den()/g); return r; } /* reduce */
fraction operator + (fraction a, fraction b) { fraction r (a.num()*b.den()+b.num()*a.den(), a.den()*b.den()); return reduce(r); } fraction operator - (fraction a, fraction b) { fraction r (a.num()*b.den()-b.num()*a.den(), a.den()*b.den()); return reduce(r); } fraction operator * (fraction a, fraction b) { fraction r (a.num()*b.num(), a.den()*b.den()); return reduce(r); } fraction operator / (fraction a, fraction b) { fraction r (a.num()*b.den(), a.den()*b.num()); return reduce(r); }
! Verwendung von Member-Funktionen.
! Initialisierung mit Default-Konstruktor.
! Initialisierung mit explizitem Konstruktor.
// fcalc.cc: a stack calculator #include <iostream.h> #include "fstack.h" #include "fract.h" int main() { char inpch; int num; cin >> inpch; while (inpch != '=') { if ('0' <= inpch && inpch <= '9') { cin.putback(inpch); cin >> num; push(num); } else
switch (inpch) { case '+': { push(pop() + pop()); break; } case '-': { fraction right_operand = pop(); push(pop() - right_operand); break; } case '*': { push(pop() * pop()); break; } case '/': { fraction right_operand = pop(); push(pop() / right_operand); break; } default: { cout << "Input Error: " << inpch << ".\n"; return 1; } } /* switch */ cin >> inpch; } /* while */ pop().print(); return 0; }
CCC = g++ # object files: O = fstack.o fcalc.o fract.o # resulting executable: R = fcalc $(R) : $(O) $(CCC) $O -o $(R) # dependencies: fstack.o: fract.h fstack.h fcalc.o: fstack.h fract.h fract.o: fract.h