¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. C++
  3. Estructuración de los datos
Extrait - C++ De los fundamentos del lenguaje a las aplicaciones (2ª edición)
Extractos del libro
C++ De los fundamentos del lenguaje a las aplicaciones (2ª edición) Volver a la página de compra del libro

Estructuración de los datos

Programación estructurada

Los lenguajes de programación empezaron muy pronto a agrupar instrucciones reutilizables, conocidos como funciones. Las variables siguieron el ejemplo, aunque un poco más tarde.

La matriz se puede utilizar para procesar determinados algoritmos, siempre que los datos a procesar sean de un tipo uniforme (char, int...). Cuando los datos a procesar contienen diferentes tipos de información, es necesario utilizar varias matrices o una única que utilice un tipo void*. Hay que reconocer que esta solución no es recomendable.

En su lugar, definimos estructuras que agrupan varias variables llamadas campos. Estas variables existen en tantas copias como quiera, cada copia se llama instancia.

El lenguaje C++ tiene varias formas compuestas:

  • Las estructuras y las uniones, basadas en la C.

  • Las clases, que se tratarán en el capítulo dedicado a la programación orientada a objetos.

1. Estructuras

Las estructuras de C++, al igual que las estructuras de C, definen nuevos tipos de datos. El nombre dado a la estructura genera un tipo de datos:

struct Persona 
{ 
  char nombre[50]; 
  int edad; 
} ; 

A partir de esta estructura Persona, ahora vamos a crear variables, siguiendo la sintaxis habitual de declaración que asocia un tipo y un nombre:

Persona angel, maria; 

angel y maria son dos variables de tipo Persona. Como son tipos no primitivos (char, int...), decimos que son instancias de la estructura Persona. El término instancia nos recuerda que el nombre y la edad son características propias de cada persona.

images/cap3_pag2.png

Para acceder a los campos de una instancia se utiliza una notación especial:

angel.edad = 50; // edad de ángel 
printf("%s",maria.nombre); // nombre de maría 

Esta notación vincula el campo a su instancia.

2. Construir una estructura

Una estructura puede contener un número ilimitado de campos. Para los lectores que se inician en este tipo de programación y están acostumbrados a las bases de datos, resulta útil comparar una estructura con una tabla de una base de datos.

C++

SQL

estructura

tabla

campo

campo / columna

instancia

registro

Por supuesto, cada campo de la estructura es de un tipo determinado. Puede ser de tipo primitivo (char, int...) o de tipo estructura. También se pueden obtener construcciones interesantes...

Estructuras y funciones

Son las funciones que operan sobre las estructuras. A menudo, las estructuras se declaran como variables locales en una función, para que se puedan utilizar como argumentos en otras funciones. Entonces, ¿cuál es la mejor forma de transmitirlas? Tenemos los tres métodos habituales: por valor, por dirección (puntero) o por referencia.

1. Pasar una estructura basada en valores como argumento

El modo por valor se recomienda si la estructura es pequeña y es necesario proteger sus valores contra cualquier modificación involuntaria, por parte de la función llamada. Este modo implica copiar todos los campos de la instancia en la pila, lo que puede llevar cierto tiempo y consumir recursos de memoria limitados. En el caso de funciones recursivas, el tamaño de la pila ya tiende a crecer rápidamente, por lo que no es buena idea sobrecargarla innecesariamente.

Sin embargo, esta copia evita cualquier efecto secundario, ya que es una copia de la estructura que se pasa.

void mostrar(Numero n) 
{ 
  switch(n.t_num) 
  { 
  case t_int: 
    printf("%d\t",n.val.num_i); 
    break; 
  case t_float: 
    printf("%f\t",n.val.num_f); 
    break; 
  case t_double: 
    printf("%f\t",n.val.num_d); 
    break;   
  } 
} 

2. Pasar una estructura por referencia como argumento

Este modo representa un avance considerable, ya que lo que se transmite es la referencia (dirección inalterable) de la estructura. Esta...

La librería estándar de C

Con las estructuras y la asignación de memoria, nos damos cuenta de que un lenguaje se debe basar en librerías del sistema para construir aplicaciones completas. C++ tiene su propia librería, pero muchos programadores siguen utilizando las funciones estándar de C.

1. Funciones comunes del lenguaje C <stdlib.h>

La librería estándar stdlib.h contiene funciones generales. Algunas funciones también se pueden declarar en otras cabeceras.

He aquí una lista que resume algunas funciones interesantes para el desarrollo cotidiano. Conviene consultar el libro El lenguaje C de Kernighan y Ritchie o la documentación suministrada con el compilador, para obtener una lista completa de funciones y sus firmas.

El libro Kernighan y Ritchie es la obra de referencia escrita por los creadores del lenguaje C. Sigue editándose y actualizándose a medida que evoluciona el lenguaje C.

Funciones

Utilidad

atoi, atof, strtod...

Funciones para convertir entre un tipo de cadena y un tipo numérico.

getenv, setenv

Acceso a las variables de entorno del sistema.

malloc, calloc

Asignación de memoria.

rand, abs

Funciones matemáticas.

La librería estándar stdlib también contiene macroinstrucciones basadas en la sintaxis #define:

Macro

Utilidad

__min, __max

Proporciona los valores mínimo y máximo de dos argumentos.

NULL

Literalmente (void*)0.

Un breve ejemplo muestra cómo utilizar el archivo:

char* lectura = new char[500]; 
printf("¿Número? "); 
scanf("%s",lectura); 
 
double numero = atof(lectura); 
double pi = 3.14159265358; 
 
printf("El número más grande es %2f\n",__max(numero,pi)); 
images/cap3_pag25.png

2. Cadenas <string.h>

El lenguaje C++ todavía gestiona sus literales de cadena en el formato char*, definido por el lenguaje C. Por lo tanto, es importante familiarizarse con las principales funciones de la librería string.h.

Funciones

Utilidad

memcpy, memcmp, memset

Vista en memoria de cadenas de caracteres: copiar, comparar, inicializar.

strcpy, strcmp, strcat, strlen

Copiar, comparar, concatenar, longitud.

strchr, strstr

Búsqueda de caracteres y subcadenas.

strlwr, strupr

Conversión de mayúsculas/minúsculas.

Veamos otro ejemplo para ilustrar el uso de esta librería:

    /* ...

Ejercicios prácticos

He aquí un programa en C++ que combina estructuras y la librería estándar de C. Se trata de una pequeña base de datos que describe estrellas y constelaciones.

1. Las estructuras

El programa incluye dos estructuras, Estrella y Constelacion, que se instancian con los nombres proxima y gran_oso respectivamente.

/* 
 * estructuras de datos e instancias  
 */ 
 
struct Estrella { 
    char* nombre; 
    float distancia_al; 
}; 
 
struct Constelacion{ 
    Estrella* estrellas; 
    int numero; 
} gran_oso; 
 
Estrella proxima; 

2. La función de inicialización

La función de inicialización es una aplicación directa de la sintaxis para definir los valores de los campos de una estructura. Nótese también el uso del operador de conversión explícito (char*) para asignar a un char* un valor const char*.

// inicializar una constelación 
void init() 
{ 
    printf("Initialización\n"); 
    gran_oso.estrellas = new Estrella[3]; 
    gran_oso.estrellas[0].nombre = (char*) "Alioth"; 
    gran_oso.estrellas[0].distancia_al = 81; 
 
    gran_oso.estrellas[1].nombre = (char*) "Dubhe"; 
    gran_oso.estrellas[1].distancia_al = 80; 
 
    gran_oso.estrellas[2].nombre = (char*) "Zeta"; 
    gran_oso.estrellas[2].distancia_al = 78; 
 
    gran_oso.numero = 3; 
} 

3. Funciones de visualización

En primer lugar, está la función to_string(), que se encarga de representar una instancia en forma de cadena. Encontraremos este mecanismo como método (función integrada) en la mayoría de las clases C++.

// transforma una instancia de estrella en una cadena 
char* to_string(Estrella estrella) 
{ 
    int tbuf = strlen(estrella.nombre) + 30; 
    char* buf = new char[tbuf]; 
    sprintf_s(buf...