Operaciones Aritméticas

Las operaciones aritméticas básicas en C++ son muy parecidas a las de otros lenguajes.

OperadorOperación
+Suma
Resta
*Multiplicación
/División
%Módulo

Una librería muy útil a la hora de realizar operaciones matemáticas es cmath. Una de sus funciones más útiles es pow().

Fíjate en su uso:

#include <cmath>

std::pow(base, exponente);

Como por ejemplo:

std::pow(2, 5);

cmath incluye también algunas constantes muy útiles a la hora de realizar operaciones matemáticas, como por ejemplo M_PI que es el equivalente al número PI.

M_PI = 3.14159265358979323846

Conversiones implícitas

Como ya sabes, C++ es un lenguaje compilado y como tal requiere conocer los tipos de variable que van a ser usados durante la ejecución.

Sin embargo se permiten ciertas conversiones implícitas, como por ejemplo un entero que se asigna a una variable de tipo float o un entero tratado como un char.

Echa un vistazo al siguiente ejemplo para comprender mejor este concepto:

#include<iostream>

int main()
{
    
    int a = 65;
    char charA = 65;
    char charB = 'B';
    float answer = 0;
    char charC = 67;
    int integer = 80;
    float floatNumber = 0.0;
    
    std::cout<<"a = "<<a<<"\n";
    std::cout<<"charA = "<<charA<<"\n";
    std::cout<<"charB = "<<charB<<"\n";
    
    // se puede asignar un integer a un float 
    floatNumber = integer;
    std::cout<<"integer = "<<integer<<"\n\n";
    std::cout<<"floatNumber = integer = "<<floatNumber<<"\n";
    
    // se puede asignar un char a un float
    floatNumber = charB;
    std::cout<<"floatNumber = charB = "<<floatNumber<<"\n";  
    
    answer = floatNumber/4;
    std::cout<<"respuesta = floatNumber/4 = "<<answer<<"\n"; 
    
    // Asignar un float a un char no funciona tan bien...
    charC = answer;
    std::cout<<"charC = respuesta = "<<charC<<"\n";
    
    // y si asignas un float a un integer el valor s truncado
    integer = answer;
    std::cout<<"integer = floatNumber = "<<integer<<"\n";   
    return 0;
}

Prefijo y postfijo

En C++, como en otros lenguajes, hay operadores que pueden funcionar como prefijos y postfijos.

Para incrementar una variable:

  • prefijo: ++a
  • postfijo: a++

Para reducir:

  • prefijo: –a
  • postfijo: a–

Existe una diferencia pequeña pero crucial entre ambas y es que el prefijo modifica el valor de la variable y después la devuelve y el postfijo crea una copia de la variable, la modifica y devuelve una copia anterior a la modificación.

Entrada y salida de datos II

Ya hemos visto anteriormente (lección anterior aquí) que para escribir en la consola usamos std::cout. De forma muy parecida tenemos std::cin para capturar la entrada desde la consola. Prueba un ejemplo:

#include <iostream>
#include <string>

int main()
{
  int pokNumber = 0;
  int pokPs = 0;
  std::string pokemon = "";
  
  std::cout<<"¿Cuántos pokemon tienes? ";
  std::cin >> pokNumber;
  
  std::cout << "No está mal, yo tengo " << pokNumber + 1 << std::endl;
  
  std::cout << "¿Cuántos PS tiene tu pokemon más fuerte? ";
  std::cin >> pokPs;
  
  std::cout<<"Está muy bien, mi Pikachu tiene "<< pokPs + 10 << " PS" << std::endl;

  std::cout<<"¿Cuál es tu pokemon favorito? ";
  std::cin >> pokemon;
  
	std::cout << "Qué casualidad! Mi pokemon favorito también es " << pokemon << std::endl;

	return 0;
}

¿Qué sucede al intentar capturar la entrada del usuario si se introducen dos palabras?

Te invito a que lo pruebes en tu propio programa y veas el resultado.

Podemos comprobar como std::cin no está pensado para capturar cadenas largas o espacios. Para ello tenemos a nuestra disposición una función llamada getline.

Su forma básica de operar es la siguiente: captura caracteres de std::cin y los almacena en la variable asignada. Se realiza esta operación hasta alcanzar una línea nueva o bien el carácter asignado, por defecto ‘\n’. Más info aquí.

#include<iostream>
#include<string>

int main()
{
    std::string apodo; 
    std::cout<<"¿Cuál es tu apodo?: ";
    std::getline(std::cin, apodo);
    std::cout<<"Hey, "<<apodo<<"!\n";
    return 0;
}

Stringstream

Esta librería resulta muy útil a la hora de manipular cadenas. Stringstream permite la manipulación de variables como si fueran streams de datos.

Para utilizarla debemos incluir la cabecera:

#include <sstream>

Fíjate en el siguiente ejemplo:

#include <string>
#include <iostream>
#include <sstream>

int main () {

  std::stringstream ss;

  ss << "pikachu" << ' ' << "bulbasaur";

  std::string pika, bulbasaur;
  ss >> pika >> bulbasaur;

  std::cout << "pokemon 1: " << foo << '\n';
  std::cout << "pokemon 2: " << bar << '\n';

  return 0;
}

Archivos de cabecera

También conocidos como header files. Como ya vimos en lecciones anteriores, podemos incluir todo tipo de librerías adicionales en C++, y podemos crear las nuestras e incluirlas también.

Generalmente los archivos de cabecera tienen la extensión .hpp, pero puedes utilizar la extensión que prefieras. Lo más importante acerca de los archivos de cabecera es que tienes que saber que son usados para definir información sobre como ejecutar una tarea, a diferencia del programa principal, que define lo que se va a ejecutar.

Veamos como un archivo de cabecera funciona con un sencillo programa ‘Hola, mundo!’

#include <iostream>

using namespace std;

int main(){
  cout << "Hola, estamos usando archivos de cabecera!";
  return 0
}

Si quisiéramos usar un archivo de cabecera para este propósito podríamos mover todo el código que no estuviera estrictamente relacionado con la tarea, de forma que podríamos generar un archivo main.hpp con el siguiente contenido:

#include <iostream>

using namespace std;

Y modificaríamos nuestro archivo principal (el que contiene la funcion main) para que quedara de la siguiente manera:

#include "main.hpp"

int main(){
  cout << "Hola, estamos usando archivos de cabecera!";
  return 0
}

Fíjate en las comillas dobles para incluir el archivo. De esta forma indicamos que se encuentra en el directorio actual.

Constantes

Hay un tipo de variable en C++ que podemos usar si queremos forzar que su valor no cambie a lo largo de la ejecución del programa, las constantes.

Hay dos formas de declarar constantes en C++:

  • Mediante la palabra clave const.
  • Utilizando el preprocesador mediante #define

Definición de constantes mediante const

El formato de esta declaración es el siguiente:

const type variable = value;

Por ejemplo:

const int pokemonCount = 898;	

Tratar de cambiar este tipo de variables nos mostrará un error. Compruébalo por tu cuenta:

#include <iostream>
using namespace std;

int main()
{
    const int pokemonCount = 898;
    cout<<"Número de pokemon = "<<pokemonCount<<"\n";
    pokemonCount = 1000;
    cout<<"Número de pokemon = "<<pokemonCount<<"\n";
    return 0;
}

Definición de constantes en la cabecera

El formato de la declaración es el siguiente:

#define identifier value

Por ejemplo:

#include <iostream>
using namespace std;

#define POKEMON_COUNT 898

int main()
{
    cout<<"Número de pokemon = "<<POKEMON_COUNT<<"\n";
    POKEMON_COUNT = 1000;
    cout<<"Número de pokemon = "<<POKEMON_COUNT<<"\n";
    return 0;
}

De nuevo nos encontraremos con un error al tratar de ejecutar este programa.

Constantes enumeradas

Hay un tipo de constante especialmente útil, las constantes enumeradas o enumerated constants. Se usan para declarar un tipo de variable y asignarle así un número finito de valores. Fíjate en este ejemplo:

enum pokemonTipo {
	PLANTA,
  	FUEGO,
    AGUA,
    LUCHA,
    BICHO,
    ELECTRICO
};

Los valores son automáticamente traducidos a enteros de tal forma que:

PLANTA = 0
FUEGO = 1
...

Fíjate en el programa de ejemplo:

#include <iostream>

using namespace std;

int main()
{
    enum POKEMON_TIPO {
    PLANTA,
  	FUEGO,
    AGUA,
    LUCHA,
    BICHO,
    ELECTRICO
      };
  
  	// definimos mejorTipo como una variable de tipo POKEMON_TIPOS
    POKEMON_TIPO mejorTipo;
    
    // hacemos una asignación
    mejorTipo = ELECTRICO;
    
    // y comprobamos como haríamos con cualquier otra variable
    if(mejorTipo == ELECTRICO)
    {
        cout<<"No me parece que ese sea el mejor tipo de pokemon\n";
    }
    return 0;
}