Universidad de Costa Rica
Facultad de Ingeniería
Escuela de Ciencias de
Tarea Programada #2
Emplantamiento de Programas
Profesor: Adofo Di Mare
Curso: Programación CI-1201
Alumno: Carlos Mejías Álvarez
Setiembre de 2007
Índice
Introducción…………………………………..3
Breve
Descripción………………………….....4
Objetivos…………………………………4
Requerimientos…………………………...4
Abstracción……………………………………5
Implementación………………………………..6
Código
Fuente………………………………….7
Introducción
Un programa emplantillado se basa
específicamente en poder programar una clase sobrecargada para la reutilización
de software.
Por medio de las plantillas y la
experiencia obtenida en este proyecto se pudo determinar el beneficio y
facilidad a la hora de manipular archivos C++ emplantillados.
Al tener un archivo emplantillado se
obtiene una serie de diferentes “tipos” de resultados según sea el tipo que le
coloquemos a la plantilla. El compilador de C++ realiza la sustitución a nivel
de depuración y compilación, permitiendo al programador utilizar esta fácil
técnica para ahorrar tiempo y optimizar su código fuente.
En la página web : http://www.geocities.com/cmejas126/index.html
se puede revisar la documentación generada por Doxygen, dando clic en el link
llamado “Documentación Doxygen” bajo el bullet de Tarea Programada 2.
Breve Descripción
Objetivos:
× Aprender a programar de manera
emplantillada las diferentes clases de un programa.
× Realizar las sustituciones pertinentes para
obtener la correcta compilación del programa.
× Probar cambiando el atributo del archivo
rat-calc.cpp por <long>, <char>, <INT>.
× Observar los distintos resultados al
realizar el objetivo anterior.
Requerimientos:
× Software para compilar programas en el
lenguaje de programación C++. Utilizado: Visual Studio.
× Software para la documentación del
programa. Utilizado: Doxygen.
× Sitio web personal para alojar diferentes
archivos solicitados por el profesor. Actual: http://www.geocities.com/cmejas126/index.html
Abstracción
Para
empezar debemos entrar al sitio web del profesor y obtener del ahí el
racional.htm. Luego se debe
descargar el archivo .zip, y de este trabajar con el proyecto llamado
rat-calc.vcproj situado en la carpeta MSCv6.
A
continuación se citan las instrucciones dadas por Adolfo Di Mare en clase:
- Quitar #include
"rational.h" del .cpp
- Copiar el .cpp en el .h antes del #endiff
- Agregar template
<class INT> antes de class rational {}
- Remplace todos los long por INT
- Eliminar el archivo rational.cpp del prooyecto y del disco duro
- Ponerle template <class INT> a toddos los métodos y funciones que están
afuera de la clase.
- Sustituir "rational::" por &quuot;rational<INT>::"
- Sustituir "rational" por "t;rational<INT>" en algunos
parámetros de métodos que no compilan
- Eliminar OPEN_namespace(ADH)
- Eliminar USING_namespace(ADH)
- Eliminar CLOSE_namespace(ADH)
- Eliminar #define INCLUDE_iostream
- Eliminar #include "ADH_port.h";
- Eliminar ADH_port.h del proyecto
- Agregar #include <iostream>
- Agregar using namespace std;
- Sustituir
"friend" por "template <class T> friend"
- Dentro de la clase sustituir todos las ffunciones friend de manera que tengan
rational<T> en lugar de rational.
- Sustituya return rational(res_num, res_dden);
por return rational<INT>(res_num, res_den);
Código Fuente
// rational.h (c)
2005 [email protected]
/** \file
rational.h
\brief Declara
el tipo \c "rational".
- La clase \c rational
implementa las operaciones aritméticas
principales
para números rationales.
- <code>
[1/3] == [2/6] == ... [9/27] == ... </code>
- <code>
[1/3] * [2/6] / [3/9] - [9/27]
</code>
- Permite usar
racionales en cualquier sitio en donde se puedan
usar valores
numéricos.
\author Adolfo
Di Mare <[email protected]>
\date 2005
*/
#ifndef rational_h
#define rational_h ///< Evita la
inclusión múltiple
#include <iostream>
using namespace std;
/** La clase \c
rational implementa las operaciones aritméticas
principales
para números rationales.
- <code>
[1/3] == [2/6] == ... [9/27]
== ... </code>
- <code> [1/3] * [2/6] /
[3/9] - [9/27] </code>
*/
template <class INT>
class rational {
private:
INT m_num; ///< Numerador
INT m_den; ///< Denominador
void Simplify();
public:
// constructores
rational() :
m_num(0), m_den(1) { } ///< Constructor de vector
rational(INT num) :
m_num(num), m_den(1) { } ///< Constructor a partir
de un valor entero
rational(INT num,
INT den)
: m_num(num),
m_den(den) { Simplify(); } ///< Constructor a
partir de un valor quedbrado
rational(const rational& o) ///
Constructor de copia
{ m_num =
o.m_num, m_den = o.m_den; }
~rational() {
} ///<
Destructor
void set(INT num=0, INT den=1); // Le cambia el
valor a \c "*this"
INT num() const { return m_num;
} ///<
Copia del numerador
INT den() const { return m_den;
} ///<
Copia del denominador
//
void num(INT n) { m_num=n; Simplify(); }
// FEO
//
void den(INT d) { m_den= ( d!=0 ? d : m_den) ; Simplify(); } // FEO
rational&
operator
= (const rational&); // Asignación
(copia)
rational&
operator
= (INT);
rational&
swap ( rational& );
rational&
operator += (const
rational&);
rational&
operator -= (const
rational&);
rational&
operator *= (const
rational&);
rational&
operator /= (const
rational&);
rational operator - () const;
// menos unario
template <class
T>
friend rational<T> operator
+ (const rational<T>&, const rational<T>&);
template <class
T>
friend rational<T> operator
- (const rrational<T>&, const rational<T>&);
template <class
T>
friend rational<T> operator
* (const rational<T>&, const rational<T>&);
template <class
T>
friend rational<T> operator
/ (const rational<T>&, const rational<T>&);
template <class
T>
friend bool operator == (const
rational<T>&, const
rational<T>&);
template <class
T>
friend bool operator <
(const rational<T>&, const rational<T>&);
template <class
T>
friend bool operator != (const rational<T>&, const rational<T>&);
template <class T>
friend bool operator <= (const
rational<T>&, const
rational<T>&);
template <class
T>
friend bool operator >= (const
rational<T>&, const
rational<T>&);
template <class
T>
friend bool operator >
(const rational<T>&, const rational<T>&);
template <class
T> friend ostream& operator << (ostream &, const rational& );
template <class
T> friend istream& operator >> (istream &, rational& );
rational&
fromString (const char*
nStr);
template <class
T>
friend double
real (const
rational& ); // Conversión a real
template <class
T>
friend INT
integer(const rational& ); // Conversión a
INT
template <class
T>
friend bool check_ok(
const rational& r ); // Ok()
// excluidos porque
producen ambigüedad con operadores aritméticos
//
operator double () { return double(m_num) / double(m_den); }
//
operator INT () { return m_num
/ m_den ; }
}; // rational
template <class INT>
INT mcd(INT x, INT y); // Calcula
el Máximo Común Divisor
/// Sinónimo de \c mcd(x,y) <code> [ inline ] </code>
template <class INT>
inline INT gcd(INT x, INT y) { return
mcd(x,y); }
/// Cambia el valor del número rational a \c
"n/d"
template <class INT>
inline void
rational<INT>::set(INT n, INT d) {
m_num = n;
m_den = d;
Simplify();
}
/** Copia desde \c "o".
- El valor
anterior de \c "*this" se pierde.
\par Complejidad:
O( \c 1 )
\returns *this
\see http://www.di-mare.com/adolfo/binder/c04.htm#sc05
*/
template <class INT>
inline rational<INT>& rational<INT>::operator = (const
rational<INT>& o) {
m_num =
o.m_num,
m_den =
o.m_den;
// sobra invocar a
"Simplify()" pues "o" ya está simplificado
return *this;
} // operator =
/** Intercambia los valores de \c "*this" y \c
"o".
\par Complejidad:
O( \c 1 )
\returns *this
\see http://www.di-mare.com/adolfo/binder/c04.htm#sc08
*/
template <class INT>
inline rational<INT>& rational<INT>::swap (
rational<INT>& o ) {
#if 1
rational
tmp = o;
o = *this;
*this = tmp;
#else
// Esto NO
funciona para objetos, métodos virtuales, etc.
char tmp[ sizeof( *this ) ];
memcpy( tmp, o,
sizeof( *this ) ); // tmp = o;
memcpy( o, *this,
sizeof( *this ) ); // o = *this;
memcpy( *this, tmp, sizeof( *this ) ); // *this = tmp;
#endif
return *this;
}
/// Asignación desde un \c
"INT".
template <class INT>
inline rational<INT>& rational<INT>::operator = (INT entero) {
m_num =
entero;
m_den = 1;
return *this;
} // operator =
/// Multiplica \c "*this"
por \c "num".
template <class INT>
inline rational<INT>& rational<INT>::operator *= (const
rational<INT>& num) {
m_num *=
num.m_num;
m_den *= num.m_den;
Simplify();
return *this;
} // operator *=
/**
Divide \c "*this" por el valor de \c "num".
\pre
- (num != 0)
*/
template <class INT>
inline rational<INT>& rational<INT>::operator /= (const
rational<INT>& num) {
m_num *=
num.m_den;
m_den *= num.m_num;
Simplify();
return *this;
} // operator /=
/// \c "-x".
/// - Menos unario
/// - Calcula y retorna el valor \c "-x"
template <class INT>
inline rational<INT> rational<INT>::operator - () const {
rational tmp
= (*this);
// tmp.rational( *this );
tmp.m_num = -
tmp.m_num;
return tmp;
} // operator -
/// ¿ x == y ?
template <class INT>
inline bool operator == (const
rational<INT> &x, const
rational<INT> &y) {
return (x.m_num == y.m_num) && (x.m_den ==
y.m_den);
/* Nota:
Como los números
racionales siempre están simplificados, no puede
ocurrir que
[1/1] está almacenado como [3/3] y en consecuencia
basta comparar
los valores campo por campo para determinar si se
da o no la
igualdad.
*/
} // operator ==
/// ¿ x < y ?
template <class INT>
inline bool operator < (const
rational<INT> &x, const
rational<INT> &y) {
return (x.m_num * y.m_den) < (x.m_den * y.m_num);
/* Nota:
Una desigualdad
de fracciones se preserva siempre que se
multiplique a
ambos lados por un número positivo. Por eso:
[a/b]
< [c/d] <==>
[(b*d)*a/b] < [(b*d)*c/d] <==>
[d*a] < [b*c]
[a/b] > [c/d] <==> [(b*d)*a/b] > [(b*d)*c/d] <==>
[d*a] > [b*c]
Debido a que el denominador
siempre es un número positivo, el
trabajo de
comparar 2 racionales se puede lograr haciendo 2
multiplicaciones
de números enteros, en lugar de convertirlos
a punto flotante
para hacer la división, que es hasta un orden
de magnitud más
lento.
*/
// return
double(x.m_num) / double(x.m_den) < double(y.m_num) / double(y.m_den);
} // operator <
/// ¿ x > y ?
template <class INT>
inline bool operator > (const
rational<INT> &x, const
rational<INT> &y) {
return (y < x);
} // operator >
/// ¿ x != y ?
template <class INT>
inline bool operator != (const
rational<INT>& x, const
rational<INT>& y) {
return !(x == y);
} // operator !=
/// ¿ x <= y ?
template <class INT>
inline bool operator <= (const
rational<INT>& x, const
rational<INT>& y) {
return !(y < x);
} // operator <=
/// ¿ x >= y ?
template <class INT>
inline bool operator >= (const
rational<INT>& x, const rational<INT>&
y) {
return !(x < y);
} // operator >=
/// Convertidor a punto flotante.
template <class INT>
inline double real(const rational<INT>& num) {
return double
(num.m_num) / double (num.m_den);
} // real()
/// Convertidor a punto fijo.
template <class INT>
inline INT integer(const
rational<INT>& num) {
return INT
(num.m_num / num.m_den);
} // integer()
#if 0
/// Convertidor
a punto fijo
template <class INT>
inline rational<INT>::operator
INT() {
return INT (m_num / m_den);
} // rational::operator INT
#endif
template <class INT>
bool check_ok_externo( const
rational<INT>& r );
// rational.cpp (c) 2005 [email protected]
/** \file rational.cpp
\brief Implementaciones para la clase \c "rational"
\author Adolfo Di Mare <[email protected]>
\date 2005
- Why English names??? ==>
http://www.di-mare.com/adolfo/binder/c01.htm#sc04
*/
#include <cstdlib>
#include <cctype>
// isdigit()
/** Verifica la invariante de la clase \c rational.
\par
<em>Rep</em> Modelo de la clase:
\code
+---+
| 3 |
<== m_num == numerador del número
racional
+---+
|134|
<== m_den == denominador del número
racional
+---+
\endcode
- http://www.di-mare.com/adolfo/binder/c03.htm#k1-Rep
\remark
Libera al
programador de implementar el método \c Ok()
-
http://www.di-mare.com/adolfo/binder/c04.htm#sc11
*/
template <class INT>
bool check_ok( const
rational<INT>& r ) {
if (&r == 0) {
/// - Invariante: ningún objeto puede estar almacenado en
la posición nula.
return false;
}
if ( ! (r.m_den > 0) ) {
/// - Invariante: el denominador debe ser un número
positivo.
return false;
}
if (r.m_num == 0) {
if ( r.m_den == 1 ) {
/// - Invariante: el cero debe representarse con
denominador igual a "1".
return true;
}
else {
return false;
}
}
if ( ! ( mcd(r.m_num, r.m_den) == 1 ) ) {
/// - Invariante: el numerador y el denominador deben ser
primos relativos.
return false;
}
return true;
} // check_ok()
/** Verifica la invariante de la clase \c rational.
\remark
Esta
implementación nos se le mete al <em>Rep</em>
(casi siempre no
es posible implementar una función como ésta).
-
http://www.di-mare.com/adolfo/binder/c03.htm#k1-Rep
\remark
Libera al
programador de implementar el método \c Ok()
-
http://www.di-mare.com/adolfo/binder/c04.htm#sc11
*/
template <class INT>
bool check_ok_no_Rep( const rational<INT>& r ) {
if (&r == 0) {
/// - Invariante: ningún objeto puede estar almacenado en
la posición nula.
return false;
}
if ( ! (r.den() > 0) ) {
/// - Invariante: el denominador debe ser un número
positivo.
return false;
}
if (r.num() == 0) {
if ( r.den() == 1 ) {
/// - Invariante: el cero debe representarse con
denominador igual a "1".
return true;
}
else {
return false;
}
}
if ( ! ( mcd(r.num(), r.den()) == 1 ) ) {
/// - Invariante: el numerador y el denominador deben ser
primos relativos.
return false;
}
return true;
} // check_ok_no_Rep()
/** Calcula el Máximo Común Divisor de los números \c
"x" y \c "y".
- <code>
mcd(x,y) >= 1 </code> siempre.
- MCD <==>
GCD: <em> Greatest Common Divisor </em>.
\pre
<code> (y
!= 0) </code>
\remark
Se usa el
algoritmo de Euclides para hacer el cálculo.
\par Ejemplo:
\code
2*3*5 == mcd(
2*2*2*2 * 3*3 * 5*5, 2*3*5 )
30 == mcd(
-3600, -30 )
\endcode
*/
template <class INT>
INT mcd(INT x, INT y) {
INT g = (x < 0 ?
-x : x); // trabbaja con valores positivos
INT r = (y < 0 ?
-y : y); // &quoot;r" es el resto
INT temp;
do {
temp = r;
r = g % r;
g = temp;
} while (0 != r);
return g;
} // mcd()
/** Simplifica el numerador y el denomidador.
- Transforma el
número rational de manera que el numerador y el
denominador
sean primos relativos, asegurando además que el
denominador es
siempre positivo.
- Si
<code>(m_num==0) ==> (m_den==1)</code>.
- Simplifica la
fracción para que \c m_num y \c m_den sean números
primos relativos
ie, <code>mcd(m_num,m_den) == 1</code>.
- Asegura que \c
m_den sea un número positivo.
- Restaura la
invariante de la clase \c rational.
*/
template <class INT>
void rational<INT>::Simplify() {
if (m_num == 0) {
m_den = 1;
}
INT divisor =
mcd(m_num, m_den);
if (divisor > 1) { // ==> (divisor
!= 0)
m_num /=
divisor;
m_den /=
divisor;
}
if (m_den < 0) {
m_num = -m_num;
m_den = -m_den;
}
} // rational::Simplify()
/// Le suma a \c "*this" el valor de \c
"otro".
template <class INT>
rational<INT>& rational<INT>::operator += (const
rational<INT>& otro) {
m_num = m_num * otro.m_den + m_den * otro.m_num;
m_den *=
otro.m_den;
Simplify();
return *this;
} // operator +=
/// Le resta a \c "*this" el valor de \c
"otro".
template <class INT>
rational<INT>& rational<INT>::operator -= (const
rational<INT>& otro) {
INT oldm_den =
m_den;
INT oldm_num =
m_num;
INT d = otro.m_den;
INT n = otro.m_num;
m_den *= d;
m_num = oldm_num *
d - oldm_den * n;
Simplify();
return *this;
} // operator -=
/// Establece el varlor de \c "*this" a partir
de la hilera \c "nStr".
/// \pre \c "nStr" debe estar escrita en el
formato "[num/den]".
template <class INT>
rational<INT>& rational<INT>::fromString (const char* nStr) {
char ch; // valor obtenido, caracter por caracter, de
"nStr"
bool es_positivo = true; // manejo de los
signos + y -
// se brinca todo hasta el primer dígito
do {
ch = *nStr;
nStr++;
if (ch == '-')
{ // cambia de
signo
es_positivo
= !es_positivo;
}
} while (!isdigit(ch));
// se traga el numerador
INT num = 0;
while (isdigit(ch)) { //
convierte a decimal: izq --> der
num = 10 * num
+ (ch-'0');
ch = *nStr;
nStr++;
}
// se brinca los blancos después del numerador
while (isspace(ch)) {
ch = *nStr;
nStr++;
}
INT den;
if (ch ==']') { // es un número entero
den = 1;
}
else {
do { // se brinca todo hasta el denominador
ch = *nStr;
nStr++;
if (ch == '-') {
es_positivo = !es_positivo;
}
} while (!isdigit(ch));
// se traga el denominador
den = 0;
while (isdigit(ch)) {
den = 10 *
den + (ch-'0');
ch = *nStr;
nStr++;
}
// Ya no importa si aparece o no el ']' del final del
número
}
// le cambia el signo, si hace falta
if (! es_positivo) {
num = -num;
}
set( num, den );
return *this;
}
/** Graba el valor de \c "r" en el flujo \c
"COUT".
- Graba el valor
en el formato [num/den].
- En particular,
este es el operador que se invoca
cuando se usa,
por ejemplo, este tipo de instrucción:
\code
cout
<< r << q;
\endcode
*/
template <class INT>
ostream& operator<<
(ostream &COUT, const
rational<INT>& r) {
if ( r.m_den == 1 ) { // no
hay parte fraccional
return COUT << "["
<< r.m_num << "]" ;
} else {
return COUT << "["
<< r.m_num << "/"
<< r.m_den << "]" ;
}
} // operator <<
/** Lee del flujo de texto \c "CIN" el valor de
\c "r".
\pre
El número
rational debe haber sido escrito usando
el formato
"[r/den]", aunque es permisible usar
algunos blancos.
- Se termina de
leer el valor sólo cuando encuentra \c "]".
- <code> [
-+-+-+-+- 4 / -- -+ -- 32 ]
</code> se lee como
<code>
[1/8] </code>
*/
template <class INT>
istream& operator
>> (istream &CIN, rational<INT>& r) {
char ch; // valor leido, letra por letra, de "CIN"
bool es_positivo = true; // manejo de los
signos + y -
// se brinca todo hasta el primer dígito
do {
CIN >>
ch;
if (ch == '-')
{ // cambia de
signo
es_positivo
= !es_positivo;
}
} while (!isdigit(ch));
// se traga el numerador
r.m_num = 0;
while (isdigit(ch)) { //
convierte a decimal: izq --> der
r.m_num = 10 *
r.m_num + (ch-'0');
CIN >>
ch;
}
// se brinca los blancos después del numerador
while (isspace(ch)) {
CIN >>
ch;
}
if (ch ==']') { // es un número entero
r.m_den = 1;
}
else {
do { // se brinca todo hasta el denominador
CIN
>> ch;
if (ch == '-') {
es_positivo = !es_positivo;
}
} while (!isdigit(ch));
// se traga el denominador
r.m_den = 0;
while (isdigit(ch)) {
r.m_den = 10 * r.m_den + (ch-'0');
CIN
>> ch;
}
// El programa se duerme si en el flujo de entrada
// NO aparece el caracter delimitador final "]",
// pues la lectura termina hasta encontrar el
"]".
while (ch != ']') {
CIN
>> ch;
}
} // corrección:
Andrés Arias <[email protected]>
// le cambia el signo, si hace falta
if (! es_positivo) {
r.m_num =
-r.m_num;
}
r.Simplify();
return CIN;
/*
no detecta
errores...
[1/0] lo lee y
no se queja
[ !#!#!$#@! 3/
aaaa 4 jajaja ] lo lee como 3/4
... pero no se
supone que el usuario cometa errores...
*/
} // operator >>
/// \c "x+y".
/// - Calcula y retorna la suma \c "x+y".
template <class INT>
rational<INT> operator
+ (const rational<INT> &x, const rational<INT> &y) {
INT res_num,
res_den;
res_den = x.m_den *
y.m_den;
res_num = x.m_num *
y.m_den + x.m_den * y.m_num;
return rational<INT>(res_num, res_den);
} // operator + ()
/// \c "x-y".
/// - Calcula y retorna la resta \c "x-y".
template <class INT>
rational<INT> operator
- (const rrational<INT> &x, const rational<INT> &y) {
INT res_num,
res_den;
res_den = x.m_den *
y.m_den;
res_num = x.m_num *
y.m_den - x.m_den * y.m_num;
return rational<INT>(res_num, res_den);
} // operator - ()
/// \c "x*y".
/// - Calcula y retorna la multiplicación \c
"x*y".
template <class INT>
rational<INT> operator
* (const rational<INT> &x, const rational<INT> &y) {
INT res_num,
res_den;
res_num =
x.m_num * y.m_num;
res_den =
x.m_den * y.m_den;
return rational(res_num, res_den);
} // operator * ()
/// \c "x/y".
/// - Calcula y retorna la división \c "x/y".
/// \pre <code> y
!= 0 </code>
template <class INT>
rational<INT> operator
/ (const rational<INT> &x, const rational<INT> &y) {
INT res_num,
res_den;
if (0 != y.m_num) {
res_num = x.m_num * y.m_den;
res_den =
x.m_den * y.m_num;
}
return rational<INT>(res_num, res_den);
} // operator / ()
// EOF: rational.cpp
#endif// rational_h
//
EOF: rational.h
/* rat-calc.cpp (c)
2005 [email protected] */
/** \file rat-calc.cpp La calculadora polimórfica de
Adolfo
*/
/** \mainpage
\section
rat-calc La calculadora polimórfica de Adolfo
Este programa es
una calculadora polimórfica muy simple
que funciona con
los siguientes objetos:
- <code>
long, int</code>: números enteros
- \c
rational: números rationales
- \c poly: polinomios
La calculadora
funciona de la siguiente manera:
- Al principio
el valor acumulado es <code> [ 0 ] </code>
- Se puede usar
cualquier de los 4 operadores aritméticos
- Para terminar
se usa el operador de salida punto "."
Traza de
ejecución:
\code
[0] > + [ 2 /
3 ]
[2/3] > / [ 6
/ 2 ]
[2/9] > * [
18 ]
[4] > - [ 45
/ 9 ]
[-1] > / [ 13
/ 8 ]
[-8/13] > * [
2 ]
[-16/13] > +
[ 7 ]
[75/13] > .
[75/13] >
\endcode
\author Adolfo
Di Mare <[email protected]>
\date 2004
- Why English
names??? ==> http://www.di-mare.com/adolfo/binder/c01.htm#sc04
*/
#include "rational.h"
#include <limits.h>
/// Función principal en la que empieza la ejecución del
programa
int main() {
rational<long> r,
// último valor ingresado
acum; // acumulador de
la calculadora
char
op; //
operación a efectuar
// inicializa el acumudador
acum = 0;
// despliega el valor inicial del acumulador
cout << acum
<< " > ";
cin >> op;
// ciclo para leer la siguiente operación a efectuar
while (op != '.') {
// valor a operar con el acumulador
cin >>
r; //
operator>> (cin, r);
// selección de la operación a realizar
switch (op) {
case '+': acum +=
r; break;
// acum.op += ( r );
case '-': acum = acum - r;
break; //
acum.op = (op- (acum, r));
case '*': acum *=
r; break;
// acum.op *= ( r );
case '/': acum = acum / r;
break; //
acum.op = (op/ (acum, r));
default:
// operación inválida
cout
<< "\n(" << op <<
")==> Operación inválida\n";
}
// despliega el nuevo valor del acumulador
cout <<
acum << " > ";
cin.ignore(INT_MAX, '\n');
cin >>
op;
}
// despliega el valor final del acumulador
cout << acum
<< " > ";
return 0;
} // main()
/*
EOF: rat-calc.cpp */