Curso de C++ Básico. Programación Orientada a Objetos [Parte 4]


Valeo08

Capullo perro no mucho
Noderador
Nodero
Noder
------------------------------------------------------------------------------
4. Tipos Estructurados de Datos
------------------------------------------------------------------------------

4.1 Tablas
Las Tablas (o arrays, matrices, vectores) son un tipo de dato estructurado
en el que todos sus componentes, que se llaman elementos, son del mismo tipo.

Las tablas se declaran de este modo:
Código:
tipoElementos nombreTabla[numeroElementos];


Algunos ejemplos:
C++:
float precios[100]; // tabla de floats

double temperaturas[600]; // tabla de double


Para acceder a los elementos de un tabla hay que escribir el nombre de la tabla
seguido por, entre corchetes, el indice del elemento en la tabla. Hay que tener en
cuenta que las tablas empiezan por el indice 0, por ello, si por ejemplo tenemos
una tabla de 50 elementos, precios[50], el primero sería el de índice 0, precios[0] y
el último el de índice 49, precios[49].

Aunque pueda parecer raro, las tablas pueden complicarse un poco:
Código:
tipoElementos nombreTabla[n][m];


Una tabla puede tener más de una dimensión, lo que equivaldría a tener en cada elemento
de la primera dimensión, de máximo "n", una cantidad máxima de elementos "m". Esto
quiere decir que en cada elemento de la primera dimensión (de máximo "n") hay (como
máximo) "m" elementos.

Aunque esto se puede recrear para más dimensiones aun, no solo para dos. Si la
tabla tiene una dimensión se le llama tabla o array bidimensional, si tiene tres, tridimensional, etc.
Ejemplos de tablas de varias dimensiones:
C++:
int tabla1[10]; // una dimensión
int tabla2[10][20]; // dos dimensiones


Ejemplos de operaciones con tablas:
C++:
int main() {
    int tabla1[5];
    int tabla2[10][10];
    int tabla3[6] = {0, 2, 4, 10, 14, 18};

    tabla1[0] = 9;
    tabla2[0][8] = 32;

    cin >> tabla3[5];

    cout << tabla3[0];
    cout << tabla2[1][1];

    return 0;
}

Algo nuevo que se ve en el ejemplo anterior es la definición de una tabla inicializando
los elementos a un determinado valor. Es fácil hacerlo, colocamos el tipo de los
elementos luego el nombre de la tabla (con sus dimensión/es) y la asignamos entre
llaves { }, los valores ordenados según los índices de la tabla.

Una cosa a tener en cuenta a la hora de trabajar con tablas es que no se pueden
realizar las operaciones de cout o cin con las tablas en sí, sino que se aplican a un
elemento de la tabla en particular.

4.2. Registros
Los Registros son un tipo de dato estructurado estático en el que sus componentes,
que se llaman campos, pueden ser (o no) de distinto tipo.

Los registros se pueden declarar de dos formas:
Código:
// La primera sería así:
struct nombreRegistro {
    tipoCampo1 nombreCampo1;
    tipoCampo2 nombreCampo2;
    tipoCampo3 nombreCampo3;
    ...
};

// La otra forma sería así:
typedef struct {
    tipoCampo1 nombreCampo1;
    tipoCampo2 nombreCampo2;
    tipoCampo3 nombreCampo3;
    ...        
} nombreRegistro;

// Importante: ambas formas acaban en ;


Un ejemplo de un registro y su utilización:
C++:
struct jugador {
    int posX;
    int posY;
    float vida;
    float escudo;
    float resistencia;
};

int main () {
    jugador jugador1, jugador2;

    jugador jugador3 = {0, 0, 100.00, 35.00, 100.00};

    jugador1.posX = 8;
    jugador1.posY = 10;

    cout << "Introduce la posicion X del jugador 2: ";
    cin >> jugador2.posX;
    cout << "Introduce ahora la posicion Y: ";
    cin >> jugador2.posY;

    cout << "\n\n";
    cout << "El jugador 3 esta en la posicion (" << jugador3.posX
        << ", " << jugador3.posY << ")."

    return 0;
}


Como veis en el ejemplo anterior se pueden declarar structs de diferentes formas,
ahora explicaré todas con el struct del ejemplo:

Esta forma declara un struct jugador con los campos si inicializar
C++:
jugador jugador1;


Esta forma además de declarar el struct, inicializa todos los campos a la vez.
Esta manera de declarar un struct es una operación de asignación seguida de,
entre llaves y en orden, los valores que se le quieran dar a los campos
C++:
jugador jugador3 = {0, 0, 100.00, 35.00, 100.00};

Por último, otra opción que existe es inicializar los campos uno a uno
para ello se coloca el nombre del struct seguido de punto (.) y el nombre
del campo que se quiere inicializar asignándolo a un determinado valor
C++:
jugador1.posX = 8;
jugador1.posY = 10;

Una posibilidad es utilizar como campo de un struct otro struct (aunque también se
pueden usar tablas u objetos). Por ejemplo:
C++:
struct alumno {
    char[50] nombre;
    char[10] dni;
    int anioNacimiento; // No se puede utilizar la ñ
    int mesNacimiento;
};

struct grupo {
    int numAlumnos;
    int codigoClase;
    alumno alumnos[20];
    alumno delegado;
};

struct colegio {
    int codigoColegio;
    int codigoPostal;
    int numAlumnos;
    int numClases;
    clase grupos[25];
    alumno[500] alumnos; // una tabla struct dentro en la definición de otro
};
 

Valeo08

Capullo perro no mucho
Noderador
Nodero
Noder
4.3. Cadenas
Las cadenas son tablas de una sola dimensión de tipo char acabada con el código ASCII
número 0, que equivale a un espacio en blanco.
Una cadena se declara así:
Código:
char cadena[20];


Aunque en la mayoría de las tablas no se pueden recibir desde el teclado ni sacarlas
directamente por pantalla (sino que solo se puede escribir/leer un elemento de la tabla),
las cadenas sí se pueden utilizar con las funciones cout o cin. Sin embargo tiene
limitaciones, si escribimos dos palabras en consola cuando utilizamos cin, solo almacenará
la primera palabra, porque para al encontrar el código ASCII 0, es decir, un espacio.
Si queremos escribir más de una palabra podemos utilizar la función gets() de la
librería "stdio.h".

C++:
int main() {
    char palabra[30];
    char frase[100];

    cout << "Escribe una palabra: ";
    cin >> palabra;

    cout << "Escribe una frase: \n";
    gets(frase);

    return 0;
}


Teniendo "cad1" y "cad2", dos cadenas, es decir, dos tablas de tipo char de una sola
dimensión, podemos aplicarle varias funciones básicas para cadenas. Para ello antes
incluimos la librería "string.h".
  • strcpy(cad1, cad2)

    La función copia cad2 en cad1. Ten en cuenta que para asignar un valor a una cadena
    no se puede utilizar el operador de asignación habitual "=". Función de tipo void.
  • strcat(cad1, cad2)

    Concatena cad2 al final de cad1. Función de tipo void.
  • strlen(cad1)

    Devuelve la longitud de cad1. Es función de tipo entero.
  • strcmp(cad1, cad2)

    Devuelve 0 si las cadenas son iguales, menor que 0 si cad1 < cad2 y mayor
    que 0 cuando cad1 > cad2. Función de tipo entero.
  • strchr(cad1, caracter)

    Devuelve el índice del elemento de cad1 donde aparece por primera vez "caracter".
  • strstr(cad1, cad2)

    Devuelve un índice de la primera vez que aparece cad2 en cad1.


4.4. Operaciones importantes con tablas

4.4.1. Esquema de recorrido
Un esquema de recorrido es una operación empleada cuando necesitamos tratar todos
los elementos de una tabla. Para recorrer una tabla empleamos tantos bucles for anidados
como dimensiones tenga la tabla (si tiene una pues un bucle). Sería así:
Código:
tipoElemento tabla[numElementos];

for (int i = 0; i < numElementos; i++) {
    // Aquí se trata el elemento i
}
// Si hay algo que tratar al final del recorrido se coloca aquí, después del bucle

Unos ejemplos de recorridos:
C++:
int tabla[50];

// Rellenar una tabla con valores desde el teclado
for (int i = 0; i < 50; i++)
    cin << tabla[i];

// Mostrar por pantalla todos los elementos de la tabla
for (int j = 0; j < 50; j++)
    cout << tabla[i] << "\n";


4.4.2. Esquema de búsqueda
Los esquemas de búsqueda se utilizan cuando no es necesario recorrer toda la tabla
pues solo estamos buscando un elemento en concreto. Al igual que con los esquemas de
recorrido, para buscar en una tabla se colocan tantos bucles while anidados como dimensiones tenga
la tabla. Así:
Código:
tipoElemento tabla[numElementos1][numElementos2];
int numBuscado;

int i = 0, j = 0;
bool encontrado = false;

while (i < numElementos1 && !encontrado) {
    j = 0;

    while (j < numElementos2 && !encontrado) {
        if (tabla[i][j] == numBuscado) {
            encontrado = true;
        } else {
            j++;
        }
    }

    i++;
}


Por ejemplo:
C++:
char palabra[20];

cout << "Escribe una palabra: ";
cin >> palabra;

int i = 0;
bool encontrado = false;

// Encontrar la letra "a" en una palabra introducida por teclado

while (i < 20 && !encontrado) {
    if (palabra[i]=='a')
        encontrado = true;
    else i++;
}

if (encontrado)
    cout << "Esta la a en la palabra en la posicion " << i;
else cout << "No esta la a";


4.5. Clases y Objetos
Una clase (class) es un tipo estructurado de datos heterogéneo donde a diferencia
del los registros, sus elementos son privados (atributos), es decir no se puede acceder
a ellos fuera de la clase, y tiene la posibilidad de tener funciones propias (métodos
en POO), que trabajen con esos atributos privados.

Una clase se declara así:
Código:
class nombreClase {
    // Aquí se declaran los atributos y métodos privados
public:
    // Aquí se declaran los métodos públicos
};


Un ejemplo de una clase:
C++:
#include <iostream>
#include <string.h>

using namespace std;
typedef char cadena[30];

class palabras {
    cadena tabla[10];
public:
    void rellenar();
    void buscar();    
};

void palabras::rellenar() {
    for (int i = 0; i < 10; i++) {
        cout << "Rellena la palabra " << i << ": ";
        cin >> tabla[i];
        cout << "\n";
    }
}

void palabras::buscar() {
    cadena input;
    bool encontrada = false;
    int i = 0;

    cout << "Introduce una palabra para buscarla en la tabla: ";
    cin >> input;

    while (!encontrada && i < 10) {
        if (strcmp(input, tabla[i]) == 0) {
            encontrada = true;
        } else {
            i++;
        }
    }

    if (encontrada)
        cout << "Se ha encontrado la palabra en la posicion " << i;
    else
        cout << "No se ha encontrado la palabra.";
}

int main() {
    palabras p;
    p.rellenar();
    p.buscar();

    return 0;
}
 

qav

No soy el mejor mod, pero soy un excepcional pato
Noderador
Nodero
Noder
Gracias, me ha encantado, buen post :D
 

Anon

🏴‍☠️
Owner
Staff
Moderador
Paladín de Nodo
Jinete de Nodo
Burgués de Nodo
Noderador
Nodero
Noder