Si conoces el uso de arrays en C, aprender como se usan estructuras y uniones te será de lo más sencillo. Visto por encima, una estructura es un array que tiene la capacidad de almacenar variables con distintos tipos y nombres. Una unión es similar a una estructura, pero solo podrá tener un valor a la vez. Si quieres aprender a usarlas, lee este tutorial.
Como ya se ha dicho, una estructura es un grupo de variables, y estas últimas pueden adoptar distintos valores, tipos y nombres.
Por norma general, una estructura se define:
struct { int edad; float velocidad; double micoche; } nombre_estructura;
Analicemos la situación. En primer lugar, en la primera línea, hay un "struct {". Struct es la palabra clave para definir una estructura en C; el corchete está para englobar el contenido de la misma. Después, hay tres variables corrientes, dentro de la estructura. Por último, un corchete cierra la estructura. Nombre_estructura; es el identificador para llamar a la estructura posteriormente.
Cabe destacar que las variables NO se pueden inicializar en el momento de la definición. Veamos un ejemplo:
struct { int edad = 43; char* nombre = "juanito"; float estatura = 10.2; } persona;
Este ejemplo dará error. Para que funcione tendremos que quitar las inicializaciones y hacer esta acción posteriormente:
struct { int edad; char* nombre; float estatura; } persona; persona.edad = 24; persona.nombre = "charles"; persona.estatura = 1.32;
Como has podido observar en el último ejemplo, para acceder a uno de los elementos de una estructura se hace del siguiente modo:
struct { ... int nomvariable; ... } nomstruct; ... nomstruct.nomvariable = 5; ...
Simple, ¿no?
A continuación hay un ejemplo que muestra el funcionamiento de una estructura dentro de un programa:
#include <stdio.h> int main(){ struct{ int edad; float estatura; char* nombre; } persona; printf( "Hola! Voy a hacerte unas preguntas:"); printf( "\nComo te llamas? : "); scanf( "%s", persona.nombre ); printf( "\nCuantos anios tienes? : "); scanf( "%d", &persona.edad ); printf( "\nCuanto mides? : "); scanf( "%f", &persona.estatura ); printf( "Te llamas %s tienes %d anios y mides %.2f", persona.nombre, persona.edad, persona.estatura ); return 0; getchar(); }
Observa que se usan como cualquier otro tipo de variables normales y corrientes, pero almacenadas dentro de un grupo.
Además, una estructura puede contener a otra:
struct{ int edad; char* nombre; struct{ int numero; char* direccion; int telefono; } vivienda; } persona;
Para acceder a la dirección, por ejemplo, habría que escribir "persona.casa.direccion;"
Aunque ya te habrás dado cuenta, he de reconocer que las estructuras apenas tienen ningún misterio pero son muy útiles, pues permite tener datos mejor agrupados y organizados. Además, una estructura no se limita a lo visto anteriormente, podemos definir arrays de estructuras y un typedef de las mismas, siendo esta parte la más interesante.
struct{ int edad; char* nombre; struct{ int numero; char* direccion; int telefono; } vivienda; } persona[10];
Ese ejemplo es el anterior, pero hemos creado 10 personas con los mismos datos. Para acceder, por ejemplo al número 3 habría que escribir:
persona[2].nombre;
Por si no ha quedado del todo claro, a continuación hay una versión modificada del último ejemplo:
/*De P22 Para Scenebeta Este programa aplica las normas de copia propias de scenebeta*/ #include <stdio.h> int main(){ int npersonas; int i = 1; struct{ int edad; float estatura; char* nombre; } persona[9]; printf( "Hola! Voy a hacerte unas preguntas:"); printf( "Cuantas personas participaran?" ); scanf( "%i", &npersonas ); for( i = 0; i < 10 ; i++ ) { printf( "\nComo te llamas? : "); scanf( "%s", &persona[i].nombre ); printf( "\nCuantos anios tienes? : "); scanf( "%d", &persona[i].edad ); printf( "\nCuanto mides? : "); scanf( "%f", &persona[i].estatura ); printf( "Te llamas %s tienes %d anios y mides %.2f", &persona[i].nombre, persona[i].edad, persona[i].estatura ); } return 0; getchar(); }
Podrás observar que es similar a cualquier tipo de array, pero aplicando las normas de estructuras.
C permite la copia de estructuras de una manera muy simple:
estructura1 = estructura2;
En primer lugar, para poder realizar eso, es necesario que ambas estructuras tengan la misma composicion de variables. Por ejemplo:
//BIEN struct{ int a; } estructura[1]; estructura[0].a = 2; estructura[1] = estructura[0]; //MAL struct{ int a; }estructura1; struct{ int j; float y; } estructura2; estructura1.a = 0; estructura2 = estructura1;
La copia de estructuras es algo sencillo, pero que puede darnos quebraderos de cabeza irresolvibles. Hasta ahora, todo lo que hemos visto es muy simple, pero ¿qué pasa si creo una estructura dentro de una función y la uso de return?
#include <stdio.h> typedef struct{ int edad; float peso; char* nombre; int* puntero; } persona; int main(){ persona copiaestructuras(); persona a; a.edad = 45; a.peso = 54.6; a.nombre = "juan pedro"; a.puntero = &a.edad; a = copiaestructuras(); printf("La edad de %s es %i", a.nombre, a.puntero); getchar(); return 0; } persona copiaestructuras(){ persona b; b.edad = 14; b.peso = 84.3; b.nombre = "pepito"; b.puntero = &b.edad; return b; }
Estamos creando una estructura de tipo auto, por lo que en cuanto se termine su ámbito, se borrará por completo, lo cual quiere decir que el puntero también, y estaremos asignando el valor de una dirección no correspondiente al programa a un puntero. Esto como mucho (al menos en windows, desconozco en otros OS) nos causará la típica ventanita con un circulito rojo y una cruz, o en el mejor de los casos un valor no esperado sin error, pero son errores de los más difíciles de encontrar.
Además, he adelantado una cosa de más adelante. Se trata del typedef
Typedef lo que hace básicamente es asignar un código encerrado entre el identificador y el typedef en cuestión para evitar partes confusas, repeticiones y demás (siempre que sea en un lugar válido). Así, el ejemplo siguiente sería lo más básico de tyedef:
//Sin typedef int funcion(){ float peso; float altura; } //Con typedef int funcion(){ typedef float decimal; decimal peso; decimal altura; }
Se entiende mejor la última, ¿verdad? Pues esto no se queda ahí. Con estructuras, podemos hacer algo similar, ahorrando trabajo:
//sin typedef int funcion(){ struct { int edad; float peso; } a, b; return 0; } //Con typedef int funcion(){ typedef struct { int edad; float peso; } persona; persona a, b; return 0; }
Así en un programa corto, puede parecer aparatoso, pero si nos fijamos en uno mayor como puede ser el último ejemplo del apartado de copia de estructuras, será más sencillo y nos ahorrará líneas. Cabe destacar que el typedef se puede usar en cualquier parte del programa.
Si sabes como funciona una estructura, esto será de lo más fácil de explicar. Una unión es un tipo de estructura que tiene una característica especial: Sólo puede tener en uso una variable a la vez. Así, se consigue ahorrar espacio en la memoria, es decir:
//Estrucutra struct{ int a; float b; char c; double d; } estructura; /*El tamaño de la estructura será (depende del compilador): 2 (int) + 4 (float) + 2 (char) + 8 (double) = 16 bytes de memoria*/ //Unión union{ int a; float b; char c; double d; } nombre_union; /*El tamaño de la unión será (depende del compilador): 8 (double)*/
Y pensarás: "Y esto por qué" muy simple: sólo puede tener un valor, por lo que toma el tamaño de la variable más grande, pudiendo tener el valor de cualquiera de ellas.
Por norma general, una unión se define:
union { int a; float b; char** j; } nombre_union;
Un ejemplo aclarará este embrollo.
#include <stdio.h> int main(){ unsigned short int selector; union { short int largo; short int ancho; } piscina; piscina.largo = 40; piscina.ancho = 30; printf("Que quieres saber acerca de mi piscina?: \n (1) Ancho\n (2)Largo\n "); scanf("%d", &selector); if( selector == 1 ) printf( "Ancho = %i", piscina.ancho ); else printf( "Largo = %i", piscina.largo ); return 0; getchar(); }
De momento esto es todo lo que has de saber acerca de uniones y estructuras. Sobre las uniones, cabe destacar que todo lo dicho acerca de estructuras se aplica a estas (adaptado), y que una unión puede contener estructuras y viceversa.
Recuerda, si quieres aprender, debes practicar con programas que aunque en un principio puedan parecer patéticos, lo agradecerás en un futuro.
Comentarios
Tengo una duda, pero mejor la expreso en codigo
Por supuesto.
Tendrías dos variables del mismo tipo.
Aunque si vas a hacer eso, es más lógico hacerlo así:
Es decir, la estructura la declaras una vez y la usas tantas veces como tu quieras.
Dennis Ritchie. Padre de C y cocreador de UNIX.
R.I.P.
Gracias ;)
:)
que funcion hace el '*' de
que funcion hace el '*' de char* nombre_variable???
puede ser que sea lo mismo que char nombre_variable[]??
saludos y gracias! ;)
Cuando pones un * entre el
Cuando pones un * entre el tipo y el nombre de la variable, significa que estas declarando un puntero de tipo char. Es decir, es una variable (el puntero) que va almacenar la direccion de una variable (la zona de memoria a la que apunta) de tipo char. Por otro lado, con esa misma declaracion puedes instanciar un array dinamico de tipo char, con lo que la variable almacenara la direccion de la primera posicion del array en memoria dinamica.
Un saludo.
El ejemplo: /*De P22 Para
El ejemplo:
Tendría de ser algo así, digo para que funcione correctamente ;)
En parte llevas razón
Y digo en parte, porque he localizado un error en tu código, y es que defines un array de estructuras con un índice de una variable que no ha sido inicializada, lo cual es extremadamente peligroso pues no sabes que saldrá. Eso no se debe hacer nunca, ya que provocaría desde resultados inesperados hasta un crasheo del programa. Solo te aviso para que tengas más cuidad lo próxima vez.
Un saludo, y feliz navidad.
PD: Siento no haberte respondido antes, pero no lo he leído hasta hoy :S
¡Iníciate en Linux fácilmente! Sólo entra aquí y comprueba que distribución se adapta mejor a tí.
Mi review: iPod Touch 4G
Tengo entendido que no es
Tengo entendido que no es necesario el typedef, sino:
struct persona {
.....
} p1, p2;
Siendo "persona" el tipo de estructura, y p1 y p2 las variables.
PD: Buente tuto ;)
Claro que no
Es que en ningún momento he dicho lo contrario :P Simplemente, que si quieres definir estructuras similares en distintas funciones, haces un typedef global y te ahorras definir dos veces :D
PD: Gracias ;-)
¡Iníciate en Linux fácilmente! Sólo entra aquí y comprueba que distribución se adapta mejor a tí.
Mi review: iPod Touch 4G
No te acostaras sin saber algo nuevo...
Tantos años programando y me acabo de enterar del truquillo del typedef cuando se usa con struct. Para aclarar un poco, las estructuras se declaran por defecto como:
pero para evitar tener que definir las variables poniendo la palabra struct, podemos definir la estructura con typedef:
Es decir que si ponemos la palabra typedef, luego nos ahorramos la palabra struct al definir la variable "estr". No es más que un truquillo, que hace lo mismo. La explicación científica es que crea un tipo NombreEstructura que significa literalmente "struct{int a;float b}", por lo que la declaración:
NombreEstructura estr;
se transforma en la fase de precompilación en:struct {int a; float b;} estr;
;).Es curioso, porque como casi siempre trabajo en C++, nunca me había puesto a pensar sobre esto, ya que en C++ no hace falta poner la palabra struct al declarar las variables.
Buen tutorial P22! A mi por lo menos me ha servido para reflexionar...
Dennis Ritchie. Padre de C y cocreador de UNIX.
R.I.P.
Corrígeme si me equivoco
pero el primer ejemplo de estructura definida como un array cometes un error, y es que creas la estructura persona[10], o sea, un array unidimensional de 10 componentes, e indicas que es de 11 componentes. Y, que yo recuerde, al declarar cualquier array el número entre corchetes siempre indicará el tamaño sin contar el 0 (oséase, que se declaran indicando el número de elementos, no el número del elemento último).
Y otra cosa, que es que si algo no tiene solución es irresoluble, no insolvible :P.
Por lo demás muy interesante el tutorial, aunque me parece que no usaba bien el typedef hasta ahora (curioso, puesto que nunca me ha dado ni error ni problemas).
Un saludo.
Para recibir ayuda por parte de otros usuarios más rápidamente, recomendamos que pongas títulos descriptivos y no utilices abreviaturas (estilo MSN) en tus post de los foros. Recuerda que accediendo al Manual del perfecto forero y las Normas de la Comunidad aprenderás trucos para resolver tus dudas antes.
Gracias por corregirme el
Gracias por corregirme el error, esa parte la hice cuando aún creía que las definiciones empezaban por 0 :P
Lo de insolvible, no lo encuentro en el tutorial :S
El typedef, podrías decirme como lo usas? Es solo por saberlo, a lo mejor se puede de varias maneras
¡Iníciate en Linux fácilmente! Sólo entra aquí y comprueba que distribución se adapta mejor a tí.
Mi review: iPod Touch 4G
En el apartado
de copiar estructuras, justo debajo del primer código de dicho apartado, pones "dolores de cabeza irresolvibles".
Respecto al typedef, lo uso tal que así:
Renombro siempre a la estructura, me parece que si no me daba error (aquí no puedo saberlo)
Salu2
Para recibir ayuda por parte de otros usuarios más rápidamente, recomendamos que pongas títulos descriptivos y no utilices abreviaturas (estilo MSN) en tus post de los foros. Recuerda que accediendo al Manual del perfecto forero y las Normas de la Comunidad aprenderás trucos para resolver tus dudas antes.
¿?
Vale, lo primero ya está localizado, ahora lo cambio :P
Respecto a lo segundo, yo lo veo igual que en el tutorial...
Lo que pasa
es que yo pensaba que tenía que renombrar la estructura porque sí. Jamás se me pasó por la cabeza que lo que en realidad hago es crearme un tipo de dato propio como quien dice, para luego usarlo tantas veces quiera.
Salu2
Para recibir ayuda por parte de otros usuarios más rápidamente, recomendamos que pongas títulos descriptivos y no utilices abreviaturas (estilo MSN) en tus post de los foros. Recuerda que accediendo al Manual del perfecto forero y las Normas de la Comunidad aprenderás trucos para resolver tus dudas antes.