Universidad de Costa Rica

Facultad de Ingeniería

Escuela de Ciencias de la Computación E Informática

 

 

 

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 */

Hosted by www.Geocities.ws

1