C++

Logo JS

Última edición el día 2020-12-14 a las 20:52.

He recopilado la siguiente información para tener un acercamiento a C++ con el propósito de aprender mas sobre el lenguaje que por defecto utilizan las placas Arduino.

Elementos básicos del lenguaje

Comentarios

Los comentarios se pueden realizar de dos tipos:

  • Comentarios de una sola línea:

// Comentario de una sola linea
  • Comentarios multilínea:

/*
Esto es un comentario multilínea
Aquí podemos establecer mas de
una linea
*/

Estructura en C++

La estructura de C++ se presenta casi idéntica a C:

#include "iostream"

using namespace std;

int main(){
    cout << "Hola mundo";

    return 0;
}

Extensión

La extensión utilizada por los archivos Python es cpp

Compilación y Ejecución

Para compilar un script en C++ debemos instalar un compilador, yo personalmente utilizo en linux GCC y el comando para instalarlo es: sudo apt install build-essential

Lo siguiente será compilar la aplicación ejecutando: g++ -o hola hola-mundo.cpp

Y ya podemos ejecutarlo del siguiente modo: ./hola

Preparación del script

Cuando creamos un nuevo script de C++ tenemos que importar la biblioteca principal del lenguaje:

Ejemplo:

// incluimos la librería principal:
#include "iostream"
// cargamos el namespace std para no tener que estar poniendolo durante todo el código:
using namespace std;

Palabras reservadas de C++

En C++ existen las siguientes palabras reservadas:

  • auto

  • const

  • double

  • float

  • int

  • short

  • struct

  • unsigned

  • break

  • continue

  • else

  • for

  • long

  • signed

  • switch

  • void

  • clase

  • default

  • enum

  • goto

  • register

  • sizeof

  • typedef

  • volatile

  • char

  • do

  • extern

  • if

  • return

  • static

  • union

  • while

Variables y tipos de datos

Variables

Las variables se definene de forma estricta, lo que significa que definimos el tipo de dato que va a tener esta durante su declaración.

Ejemplo:

int edad = 25;

Constantes

Las constantes se definen de dos formas tal y como se hace en C.

  • En la cabecera con #define:

#include <iostream>
using namespace std;

// definir constante:
#define PI 3.1416;

int main(){
    // imprimir la constante:
    cout << "El valor de PI es: " << PI;

    return 0;
}
  • En las funciones con const:

#include <iostream>
using namespace std;


int main(){
    // declaramos la constante con const:
    const float PI = 3.1416;

    cout << "Mostrando el valor de PI: " << PI << endl;

    return 0;
}
..important

Se recomienda el uso de const ya que del otro modo es mas difícil trabajar con la salida estandar.

Tipos de datos primitivos

Los tipos de datos mas comunes son los siguientes:

Tipo de dato

Denominación

Ejemplo

void

Vacío, nada, no retorno

int

Número Entero

20, 5, -3, 0

float

Número con decimales

20.53, 12.5, -18.353

double

Número con decimales mas preciso

20.53, 12.5234, -18.35332

bool

Verdadero o falso

True, False

char

caracter o conjunto de caracteres

«a», «x», «patata»

Ejemplos:

#include <iostream>
using namespace std;

int main(){
    // tipo char:
    char x = 'a';

    // tipo entero:
    int entero = 10;

    // tipo flotante:
    float decimal = 3.5;

    // operaciones:
    float resultado = entero + decimal;

    // booleano:
    bool valor = false;

    // impresión de resultado:
    cout << resultado << endl;

    return 0;
}

Entrada y Salida de datos

La entrada y salida de datos en C++ es algo peculiar, pese a que se puede utilizar printf() y scanf() es mas recomendable utilizar cout y cin

  • Entrada de datos:

cout << "introduce un número: << endl;
cin >> numero;
  • Salida de datos:

// salida estandar:
cout << "Hola amigo" << " así se puede " << " unir cadenas " endl; // endl salto de página o \n.

// uso de variables:
cout << "Tu número es " << numero << endl;

Operadores

Operadores Aritméticos

Los operadores aritméticos que se presentan en C++ son los siguientes, +, -, *, /, %

Estos podemos utilizarlos del siguiente modo:

// asignación:
int suma = 2 + 2;

// salida de datos:
cout << 3 - 2 << endl;

Operadores Relacionales

Los operadores relacionales en C++ son muy comunes en la mayoría de lenguajes de programación:

Operador

símbolo

Mayor que

>

Menor que

<

Igual que

==

Distinto que

!=

Mayor igual que

>=

Menor igual que

<=

Cuando hablamos del uso de un solo = nos referimos a la asignación de un valor en una variable.

Como en muchos lenguajes, si imprimimos por consola la relación entre un valor y otro el resultado será 0 o 1 (false o true):

// Si decimos que 3 es mayor que 2
cout << 3 > 2 << endl;
// el resultado que sale por consola es 1 (o sea positivo o true).

Operadores de Incremento

Este tipo de operador suma o resta 1 a la cantidad asignada, se utiliza sobre todo en bucles:

  • Incremento positivo: a++ , ++a

  • Incremento negativo: a-- , --a

Operadores de Incremento al asignar

Los operadores de incremento realizan una operación aritmética al asignar un número nuevamente:

Operador

símbolo

Sumar

+=

Restar

-=

Multiplicar

*=

Dividir

/=

Sacar resto

%=

Menor igual que

<=

Ejemplo de uso:

#include "iostream"

using namespace std;

int main() {
    int numero = 10;

    numero += 15;
    cout << numero << endl;

    return 0;
}

Operadores Lógicos

En C++ existen los operadores lógicos AND y OR:

Operador

símbolo

condición

&& (and)

&&

La condición se cumple si todos son verdaderos

|| (or)

||

La condición se cumple si al menos uno es verdadero

! (not)

!=

La condición se cumple si el valor comparado es distinto

Ejemplos:

#include "iostream"

using namespace std;

int main(){
    int edad = 67;

    // pregunta con AND:
    if(edad > 18 && edad >= 65){
            cout << "con " << edad << " años eres un anciano" << endl;
    }

    //pregunta con OR:
    if(edad > 18 || edad >= 65){
            cout << "con " << edad << " años eres mayor de edad" << endl;
    }

    // pregunta con NOT:
    if(edad != 100){
        cout << " con " << edad << " no tienes un centenar de años " << endl;
    }

    return 0;
}

Estructuras de control

En python disponemos de estructuras de control como if, for y while.

Condicional if

Las condiciones sencillas en C++ funcionan del siguiente modo:

#include <iostream>
#include <string>

using namespace std;


int main(){
    int resultado = 0;

    cout << "Cuanto es 39+50?" << endl;
    cin >> resultado;

    if(resultado == 39+50){
        cout << "Respuesta Correcta!" << endl;
    }

    return 0;
}

También tenemos condiciones con una salida alternativa si no se cumple esta:

#include <iostream>
#include <string>

using namespace std;


int main(){
    int resultado = 0;

    cout << "Cuanto es 39+50?" << endl;
    cin >> resultado;

    if(resultado == 39+50){
        cout << "Respuesta Correcta!" << endl;
    }else{
        cout << "Respuesta incorrecta, el resultado es: " << 39+50 << endl;
    }

    return 0;
}

Condicional else-if

Las condiciones compuestas nos ofrecen varios caminos posibles:

#include <iostream>

using namespace std;


int main(){
    int edad = 0;

    cout << "¿Qué edad tienes?" << endl;
    cin >> edad;

    if(edad >= 18){
        cout << "Eres mayor de edad!" << endl;
    }else if(edad >=16 && edad < 18){
        cout << "Eres un adolescente " << endl;
    }else{
        cout << "Eres menor de edad" << endl;
    }

    return 0;
}

Condicional switch

Con Switch podemos tomar varios camino en el código:

#include <iostream>

using namespace std;


int main(){
    cout << "Elije una opción: ";
    int opcion;
    cin >> opcion;

    switch(opcion){
        case 1:
            cout << "Has seleccionado la primera opción" << endl;
            break;
        case 2:
            cout << "Has seleccionado la segunda opción" << endl;
            break;
        case 3:
            cout << "Has seleccionado la tercera opción" << endl;
            break;
        default:
            cout << "Opción incorrecta" << endl;
    }

    return 0;
}

Bucle for

El bucle for en Cpp se presenta de un modo muy similar a C:

  • Uso con rango definido:

#include <iostream>

using namespace std;


int main(){

    for(int i=10; i > 0; i--){
        cout << "Cuenta atras... "<< i << endl;
    }

    return 0;
}

Bucle foreach

El bucle foreach esta diseñado especialmente para recorrer arrays y colecciones de datos.

Ejemplo de uso:

#include <iostream>
using namespace std;

int main()
{
    int numeros[] = { 8, 154, 32, 25 };

    for (int num : numeros){
        cout << num << endl;
    }

}

Bucle while

El bucle While es similar a otros lenguajes:

Ejemplo:

#include <iostream>

using namespace std;


int main(){

    int numero;
    cout << "Introduce un número" << endl;
    cin >> numero;
    while(numero <= 100){
        cout << "Introduce un número" << endl;
        cin >> numero;
    }

    return 0;
}

Ejemplo con bucle infinito:

#include <iostream>

using namespace std;


int main(){

    int numero;
    numero = 0;
    while(1){
        numero++;
        cout << numero << endl;
    }

    return 0;
}

Bucle do-while

Cuando trabajamos con do while tenemos que saber que el algoritmo se ejecutará al menos una vez aunque no se cumpla la condición:

#include <iostream>

using namespace std;


int main(){

    int numero;
    cout << "Introduce un número" << endl;
    cin >> numero;
    do{
        cout << "Introduce un número" << endl;
        cin >> numero;
    }while(numero <= 100);

    return 0;
}

Romper un bucle

Para romper un bucle while o for se utiliza la palabra reservada break:

#include <iostream>

using namespace std;


int main(){

    int numero;
    numero = 0;
    while(1){
        numero++;
        cout << numero << endl;

        if(numero == 100){
            break;
        }
    }

    return 0;
}

Estructuras de datos

Arrays o Vectores

Los arrays o vectores son una colección de datos estrictamente definida en el caso de C++

  • Ejemplo de uso e impresión de array:

#include <iostream>

using namespace std;


int main(){
    // declaración y asignación de elementos al array:
    int edades[] = {1,2,9,10,16,32,33,22,15};

    // estableciendo el tamaño de la cadena, algo similar a la función length en otros lenguajes:
    int limite = (sizeof(edades)/sizeof(edades[0]));

    // Recorrido e impresión del array:
    for(int i = 0; i < limite; i++){
        cout << edades[i] << endl;
    }

    // cambiando el valor de un elemento de la cadena:
    edades[2] = 27;
    // impresión de un valor específico del array:
    cout << edades[2] << endl;

    return 0;
}

Matrices

Las matrices son básicamente arrays multidimensionales a los que les asignamos una cantidad de casillas y este se puede representar como una tabla a la hora de guardar y acceder a la información:

  • Ejemplo de Matriz y recorrido e impresión como si fuese una tabla con un for anidado:

# include "iostream"

using namespace std;

int main(){
    // creamos una matriz de 4x4
    int matriz[4][4] = {
        {1,2,3,4},
        {4,5,6,7},
        {8,9,10,11},
        {12,13,14,15}
    }; // el primer array representa las filas y el segundo las columnas

    // impresión del número 11:
    cout << matriz[2][3] << endl;

    // recorrer matriz con un bucle anidado:
    for(int fila = 0; fila <= 3; fila++){
        cout << "==============" << endl;
        cout << "|";
        for(int columna = 0; columna <= 3; columna++){
            cout << matriz[fila][columna] << "|";
        }
        cout << endl;
    }
}

Funciones

Las funciones en C++ son practicamente iguales a C:

#include <iostream>
#include <string>

using namespace std;

int funcion(int num1, int num2){
    return num1 + num2;
}

int main(){
    cout << "el total es: " << funcion(10, 15) << endl;

    return 0;
}

Punteros

Vamos a ver un sencillo ejemplo del uso de punteros en C++:

#include <iostream>

using namespace std;

int funcion(int valor){
    valor = valor + 10;
    return valor;
}

int funcionPunteros(int* valor){
    *valor = *valor + 10;
    return *valor;
}

int main(){
    int numero = 10;

    cout << "Antes de función " << numero << endl;
    funcion(numero);
    cout << "Después de funcion " << numero << endl;

    cout << "Antes de funcionPunteros " << numero << endl;
    funcionPunteros(&numero);
    cout << "Después de funcionPunteros " << numero << endl;

    return 0;
}

Clases

El gran avance de C++ frente a C tradicional es la inclusión del paradigma orientado a objetos.

  • Creación de clases con atributos, metodo y creación del objeto:

#include <iostream>
using namespace std;

// creamos la clase:
class MiClase {
    public: // definimos el tipo de encapsulación si es publica o privada
        // definimos los atributos
        int numero;
        string cadena;
        // y esto es un método de ejemplo:
        void miMetodo(){
            cout << "Metodo de prueba" << endl;
        }
        // metodo que recibe parámetros:
        void conParametros(int edad){
            cout << "Tienes " << edad << " años." << endl;
        }
}; // las clases se cierran con ;

int main(){
    // creamos un objeto a partir de la clase anterior:
    MiClase miObjeto;

    // podemos acceder directamente a sus atributos
    miObjeto.numero = 20;
    miObjeto.cadena = "Texto de prueba";

    // imprimimos los valores:
    cout << miObjeto.numero << endl;
    cout << miObjeto.cadena << endl;
    // llamar a un método:
    miObjeto.miMetodo();
    // llamar a un metodo y enviar un parámetro:
    miObjeto.conParametros(33);

    return 0;
}
  • Clases con constructor:

#include <iostream>
using namespace std;

class MiClase {
    public:
        string nombre;
        int edad;

        // el constructor lleva el nombre de la clase y puede recibir parametros:
        MiClase(string n, int e){
            nombre = n;
            edad = e;

            cout << "Objeto creado con éxito" << endl;
        }

        void presentacion(){
            cout << "Te llamas " << nombre << " y tienes " << edad << " años." << endl;
        }
};

int main(){
    MiClase miObjeto("Felipe", 37);

    miObjeto.presentacion();
    return 0;
}

Tipos de encapsulación en C++

Existen tres tipos de encapsulación en C++:

  • public: los atributos y métodos son publicos y por tanto se puede acceder a ellos una vez creado el objeto.

  • private: los atributos y metodos no pueden ser llamados o modificados desde el objeto.

  • protected: los atributos y metodos solo pueden ser llamados o modificados desde la clase.

Get y Set

Para manejar atributos y metodos privados utilizaremos los get y set, estos metodos son una convención en programación:

#include <iostream>
using namespace std;

class MiClase {
    // cada atributo o metodo lo manejaremos en su propia capa de encapsulación.
    private:
        int numA;
    public:
        // Con los setter modificamos el atributo:
        void setNumero(int n){
            numA = n;
        }

        // y con los getter recuperamos el atributo, debemos poner el tipo de devolución como en las funciones:
        int getNumero(){
            return numA;
        }
};

int main(){
    MiClase numeros;

    numeros.setNumero(27);
    cout << "El numero establecido es: " << numeros.getNumero() << endl;
}

Herencia

La herencia en C++ se realizaría del siguiente modo:

#include <iostream>
using namespace std;

// clase padre:
class Mueble {
    public:
        string mueble = "Mesa";
        void accion(){
            cout << "PONER LA MESA" << endl;
            cout << "=============" << endl;
        }
};

// clase hijo que hereda del padre:
class MesaComedor: public Mueble {
    public:
        string tipo = "Mesa del comedor";
};

int main(){
    MesaComedor mesa;

    mesa.accion();
    cout << "Hay que poner la " << mesa.mueble << endl;
    cout << "¿Qué mesa?" << endl;
    cout << "La " << mesa.tipo << endl;
}

Importante

En la herencia de clases existe otro concepto llamado polimorfismo y se basa en reutilizar los metodos de las clases padre para modificarlos en las clases hijo de forma que podemos reutilizarlos sin necesidad de crear unos nuevos.

Manejo de errores

El manejo de errores en C++ se realiza con try y catch:

#include <iostream>
using namespace std;

int main(){
    int numeroA;
    int numeroB = 20;
    int total;

    cout << "introduce un número:" << endl;
    cin >> numeroA;
    total = numeroA + numeroB;

    // con try probaremos a ejecutar una operación:
    try{
        // si el valor es mayor a 20 siginfica que el numeroA no es una letra o un valor igual menor que 0:
        if(total > 20){
            cout << "El resultado de la suma es: " << total << endl;
        }else{
            // sino provocaremos un error:
            throw(numeroA);
        }
    } // catch caputará el error provocado:
    catch(int numero){
        cout << "El valor introducido no es correcto: " << numero << endl;
    }
}

Librerías de C++

Estas son las librerías estándares mas comunes de C++:

  • fstream: permite la manipulación de archivos desde el programa, tanto leer como escribir en ellos.

  • oisfwd: contiene declaracioens adelantadas de todas las plantillas de flujos.

  • iostream: Parte del STL que contiene los algoritmos estándar. Es la más usada.

  • list: Parte de la STL relativa a contenedores tipo list.

  • math: Contiene los prototipos de las funciones y otras definiciones.

  • memory: utilidades relativas a la gestión de memoria

  • new: manejo de memoria dinámica

  • numeric: parte de la libería numérica de la STL

  • ostream: Algoritmos estandar para los flujos de salida.

  • queue: contenedores tipo queue (colas de objetos).

  • stdio: contiene los prototipos de las funciones, macros y tipos para manipular datos de entrada y salida.

  • stdlib: lo mismo para uso general

  • string: para trabajar cadenas de texto.

  • typeinfo: mecanismo de identificación de tipos en tiempo de ejecución

  • vector: para trabajar las matrices unidimensionales.

  • forward_list: sirve para implementar listas enlazadas simples.

  • iterator: porporciona un conjunto de clases para interar elementos.

  • regex: proporciona fácil acceso al uso de expresiones regulares

  • thread: util para trabajar programas multihilos y crear varios hilos en nuestra aplicación.

Módulos y paquetes

He estado buscando información en la red y no he dado con mucho así que he comprobado que se puede crear paquetes del mismo modo que C.

  • Archivo modulo.cpp con la función del paquete:

int sumar(int num1, int num2){
    return num1 + num2;
}
  • Archivo de intercambio intercambio.h:

extern int sumar(int a, int b);
  • Archivo main.cpp con el código principal:

#include "iostream"
#include "intercambio.h"

using namespace std;

int main(){
    cout << sumar(20,15) << endl;
}

Uso del preprocesador

Este ejemplo de preprocesado sin utilizar el archivo .h es identico al de C.

  • Archivo modulo.cpp con la función del paquete:

int sumar(int num1, int num2){
    return num1 + num2;
}
  • Archivo main.cpp con el código principal:

#include "iostream"
extern int sumar(int a, int b);

using namespace std;

int main(){
    cout << sumar(20,15) << endl;
}