Un struct
es una manera de juntar un grupo de variables
en una estructura. Cuando se crea un struct
, se pueden
crear varias instancias de este «nuevo» tipo de
variable que ha inventado. Por ejemplo:
//: C03:SimpleStruct.cpp struct Structure1 { char c; int i; float f; double d; }; int main() { struct Structure1 s1, s2; s1.c = 'a'; // Select an element using a '.' s1.i = 1; s1.f = 3.14; s1.d = 0.00093; s2.c = 'a'; s2.i = 1; s2.f = 3.14; s2.d = 0.00093; } ///:~
Listado 3.44. C03/SimpleStruct.cpp
La declaración de struct
debe acabar con una llave. En
main()
, se crean dos instancias de
Structure1
: s1
y
s2
. Cada una de ellas tiene su versión
propia y separada de c
, I
,
f
y d
. De modo que
s1
y s2
representan
bloques de variables completamente independientes. Para
seleccionar uno de estos elementos dentro de
s1
o s2
, se utiliza un
., sintaxis que se ha visto en el cápitulo
previo cuando se utilizaban objetos class
de C++ - ya
que las clases surgían de struct
s, de ahí proviene esta
sintaxis.
Una cosa a tener en cuenta es la torpeza de usar
Structure1
(como salta a la vista, eso sólo se
requiere en C, y no en C++). En C, no se puede poner
Structure1
cuando se definen variables, se debe
poner struct Structure1
. Aquí es donde
typedef
se vuelve especialmente útil en C:
//: C03:SimpleStruct2.cpp // Using typedef with struct typedef struct { char c; int i; float f; double d; } Structure2; int main() { Structure2 s1, s2; s1.c = 'a'; s1.i = 1; s1.f = 3.14; s1.d = 0.00093; s2.c = 'a'; s2.i = 1; s2.f = 3.14; s2.d = 0.00093; } ///:~
Listado 3.45. C03/SimpleStruct2.cpp
Usando typedef
de este modo, se puede simular (en C;
intentar eliminar el typedef
para C++) que
Structure2
es un tipo predefinido, como
int
o float
, cuando define
s1
y s2
(pero se ha de
tener en cuenta de que sólo tiene información - características
- y no incluye comportamiento, que es lo que se obtiene con
objetos reales en C++). Observe que el struct
se ha
declarado al principio, porque el objetivo es crear el
typedef
. Sin embargo, hay veces en las que sería
necesario referirse a struct
durante su definición. En
esos casos, se puede repetir el nombre del struct
como
tal y como typedef
.
//: C03:SelfReferential.cpp // Allowing a struct to refer to itself typedef struct SelfReferential { int i; SelfReferential* sr; // Head spinning yet? } SelfReferential; int main() { SelfReferential sr1, sr2; sr1.sr = &sr2; sr2.sr = &sr1; sr1.i = 47; sr2.i = 1024; } ///:~
Listado 3.46. C03/SelfReferential.cpp
Si lo observa detenidamente, puede ver que
sr1
y sr2
apuntan el uno
al otro, guardando cada uno una parte de la información.
En realidad, el nombre struct
no tiene que ser lo mismo
que el nombre typedef
, pero normalmente se hace de esta
manera ya que tiende a simplificar las cosas.
En los ejemplos anteriores, todos los structs
se
manipulan como objetos. Sin embargo, como cualquier bloque de
memoria, se puede obtener la dirección de un objeto
struct
(tal como se ha visto en
SelfReferential.cpp
). Para seleccionar
los elementos de un objeto struct
en particular, se
utiliza un ., como se ha visto
anteriormente. No obstante, si tiene un puntero a un objeto
struct
, debe seleccionar un elemento de dicho objeto
utilizando un operador diferente: el ->. A
continuación, un ejemplo:
//: C03:SimpleStruct3.cpp // Using pointers to structs typedef struct Structure3 { char c; int i; float f; double d; } Structure3; int main() { Structure3 s1, s2; Structure3* sp = &s1; sp->c = 'a'; sp->i = 1; sp->f = 3.14; sp->d = 0.00093; sp = &s2; // Point to a different struct object sp->c = 'a'; sp->i = 1; sp->f = 3.14; sp->d = 0.00093; } ///:~
Listado 3.47. C03/SimpleStruct3.cpp
En main()
, el puntero
sp
está apuntando inicialmente a
s1
, y los miembros de s1
se inicializan seleccionándolos con el ->
(y se utiliza este mismo operador para leerlos). Pero luego
sp
apunta a s2
, y esas
variables se inicializan del mismo modo. Como puede ver, otro
beneficio en el uso de punteros es que pueden ser redirigidos
dinámicamente para apuntar a objetos diferentes, eso proporciona
más flexibilidad a sus programas, tal como verá.
De momento, es todo lo que debe saber sobre struct
,
pero se sentirá mucho más cómodo con ellos (y especialmente
con sus sucesores mas potentes, las clases) a medida que
progrese en este libro.