En muchos casos, el modelado de un problema requiere de elementos compuestos:
- El nombre completo de una persona por ejemplo, está compuesto por:
- Nombre(s).
- Primer apellido.
- Segundo apellido.
El nombre completo de una persona podría ser un elemento miembro de otra estructura, y si el modelado del problema requiere de dicho nivel de especificación, convendría considerarlo como una entidad aparte.
- Un automóvil está compuesto de varias partes, que a su vez están compuestas por otras tantas:
- Motor (combustión interna de gasolina):
- Sistema de enfriamiento.
- Sistema eléctrico.
- Bujías.
- Cilindros.
- Pistones.
- Válvulas.
- Levas.
- Inyectores.
- etcétera (bastante amplio por cierto).
- Puertas:
- Sistema de apertura y cierre.
- Sistema eléctrico.
- Cristales.
- Seguros.
- Barras de protección.
- etcétera.
- etcétera.
- Los elementos geométricos son un excelente ejemplo de composición:
- Un vértice en el espacio bidimensional está compuesto por un par ordenado de coordenadas o puntos (x, y).
- Un triángulo en el espacio bidimensional está definido por un conjunto de tres vértices.
- Un cuadrado está compuesto por cuatro vértices equidistantes entre sí.
En el lenguaje de programación C no es posible definir una estructura dentro de otra estructura, lo cual quiere decir que no se pueden definir estructuras anidas; sin embargo, sí es posible definir estructuras cuyos elementos miembro sean otras estructuras, es decir, elementos miembro cuyo tipo de dato es algún otro tipo de estructura distinta de ella misma, siempre y cuando esta última haya sido definida antes que la primera. Cabe mencionar que existe una excepción a esta regla: se puede definir una variable que haga referencia a una estructura del mismo tipo, es decir, una variable de tipo apuntador a la estructura que la define, lo cual es útil para la construcción de estructuras de datos como listas, pilas, colas, árboles, etcétera, pero estos conceptos quedan fuera del alcance de este blog y no se tratarán aquí.
El Ejemplo 8.3 muestra la definición y el uso de estructuras compuestas para un par de elementos geométricos definidos en el espacio bidimensional: el vértice y el triángulo.
La definición de las estructuras VERTICE y TRIANGULO ocurren en las líneas 7-10 y 12-16 respectivamente. Note cómo los elementos miembro de la estructura TRIANGULO son del tipo VERTICE, por lo que la estructura VERTICE ha tenido que definirse antes que la estructura TRIANGULO.
El Ejemplo 8.3 muestra la definición y el uso de estructuras compuestas para un par de elementos geométricos definidos en el espacio bidimensional: el vértice y el triángulo.
La definición de las estructuras VERTICE y TRIANGULO ocurren en las líneas 7-10 y 12-16 respectivamente. Note cómo los elementos miembro de la estructura TRIANGULO son del tipo VERTICE, por lo que la estructura VERTICE ha tenido que definirse antes que la estructura TRIANGULO.
La función principal main declara en la línea 23, una variable t de tipo TRIANGULO, lee dicho triángulo (línea 25), y presenta el triángulo que acaba de ser leído en la salida estándar (línea 26).
Por otro lado, la función leeVertice (líneas 40 - 43) recibe una referencia a una variable de tipo VERTICE, la cual es necesaria debido a que la función es para la lectura de datos. Observe una vez más el uso del operador flecha (línea 42) para la lectura de datos de los elementos miembro referidos por v; y que la cadena de especificación de formato de entrada ("%d, %d") contiene una coma (,), la cual no tiene otro fin más allá del estético en base al formato de entrada sugerido, tal y como se muestra en la siguiente figura:
Por otro lado, la función leeVertice (líneas 40 - 43) recibe una referencia a una variable de tipo VERTICE, la cual es necesaria debido a que la función es para la lectura de datos. Observe una vez más el uso del operador flecha (línea 42) para la lectura de datos de los elementos miembro referidos por v; y que la cadena de especificación de formato de entrada ("%d, %d") contiene una coma (,), la cual no tiene otro fin más allá del estético en base al formato de entrada sugerido, tal y como se muestra en la siguiente figura:
Una posible salida para el Ejemplo 8.3. |
La función leeTriangulo (líneas 31 - 38) por otra parte, se basa o apoya en la función leeVertice descrita con anterioridad para leer los tres vértices que conforman un triángulo. Note que la función también recibe una referencia almacenada en t, y que dicha referencia es utilizada en las líneas 33, 35 y 37 para pasar a su vez la referencia respectiva al vértice correspondiente a la función leeVertice. Asegúrese de comprender ésto antes de continuar.
Por último, la función imprimeTriangulo (líneas 45 - 49) imprime en la salida estándar los vértices del triángulo utilizando el operador punto para acceder, de izquierda a derecha, a los elementos miembro de la estructura compuesta:
Por último, la función imprimeTriangulo (líneas 45 - 49) imprime en la salida estándar los vértices del triángulo utilizando el operador punto para acceder, de izquierda a derecha, a los elementos miembro de la estructura compuesta:
- Línea 46: para el triángulo t, de su vértice v1, el valor correspondiente a x (t.v1.x); y para el triángulo t, de su vértice v1, el valor correspondiente a y (t.v1.y).
- Línea 47: para el triángulo t, de su vértice v2, el valor correspondiente a x (t.v2.x); y para el triángulo t, de su vértice v2, el valor correspondiente a y (t.v2.y).
- Línea 48: para el triángulo t, de su vértice v3, el valor correspondiente a x (t.v3.x); y para el triángulo t, de su vértice v3, el valor correspondiente a y (t.v3.y).