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