Sei sulla pagina 1di 6

Lenguaje C

Estructuras
Al estudiar el captulo de funciones, aprendimos la estrategia: Divide y Vencers; ahora aprenderemos la inversa: La unin hace la
esfuerza, la cual se implementa, tambin, en dos pasos:
1)

Conocer las componentes (partes) individuales, lo cual ya lo hemos hecho, por ejemplo:
int
codigo;
char nombre[25];
int
edad;
Estas tres variables pueden referirse, por ejemplo, a un estudiante; pero no lo reflejan, les falta cohesin.

2) Cohesionar las componentes para formar una estructura con un nombre que represente la cohesin.
sintaxis de una estructura:
struct [MisDatos] {
tipo1 campo1;
tipo2 campo2;
.....
} [miDato1, miDato2, .];
// Declaracin de variables de tipo struct MisDatos
// note las partes [opcionales]
Donde:
MisDatos es el nombre de estructura
miDato1, miDato2, . son variables del tipo struct MisDatos.
Es un error omitir las dos partes opcionales:
struct {
tipo1 campo1;
.....
};
Porque la estructura no tiene nombre, por lo tanto no puede ser referida.
Una estructura define a un tipo de dato complejo que agrupa a varios tipos de dato (simples o complejo); suele definirse como
global (antes de todas las funciones) para ser usada en todo el programa; recuerde que se recomend reducir el uso de variables
globales.
Admrete, algrate !!!! Estamos usando magistralmente un principio fundamental de integracin universal que lo usan todas las
ciencias, la gestin y el sentido comn. Practquelo y aplquelo.
Atento: Este procedimiento da el fundamento lgico a la estrategia La unin hace la fuerza. Para aplicarlo a las ciencias sociales; se
debe complementar con los sentimientos: responsabilidad personal, complementariedad, afectos, etc.

Definicin, referencia, lectura, escritura, asignacin e impresin de variables de tipo struct


En lo posible estas operaciones son similares a las que se hacen con datos de tipo primario:
Donde es razonablemente claro utilizar la estructura, se la usa;
Si n, se usan los campos de la estructura.
Definicin de variables:
Se puedes definir de dos formas equivalentes:
struct Estudiantes {
int codigo;
char nombre[25];
} est1, . ;
// forma 1
struct Estudiantes est2, ...;

// forma 2.

struct Estudiantes est3 = {124, "Jos Vargas"};

// define y asigna valores

est1.codigo = 123;
strcpy(est1.nombre, "Mara Mar");

// asina valor a la variable est1.codigo


// asina valor a la cadena est1.nombre

scanf(%d, &est1.codigo);
scanf(%s, est1.nombre);
printf(%d, est1.codigo);
printf(%s, est1.nombre);

// lee un entero
// lee una cadena

PGINA: 1

Lenguaje C
Ejemplo:
struct Estudiantes {
int codigo;
char nombre[25];
int edad;
} est1, est2, est3;
La definicin anterior es equivalente a:
struct Estudiantes {
int codigo, edad;
char nombre[25];
};
struct Estudiantes est1, est2, est3;

// define la estructura

// define las variables de tipo Estudiantes.

Ejemplo: Defina los estudiantes est1, est2 y est3, asigne valores e imprima los nombres:
Programa 09_01.c:
// Definir, asignar valores e imprimir datos a una esturctura
#include<stdio.h>
#include<string.h>
void main(void){
struct Estudiantes {
int codigo;
char nombre[25];
int edad;
} est1 = {123, "Carlos Rodrguez", 25};
// asigna valores a est1
struct Estudiantes est2 = {124, "Jos Vargas", 51}, est3;
// est3 = {125, "Mara Mar", 23};
Error: No compila
est3.codigo = 125;
// asignacin a cada campo
strcpy(est3.nombre, "Mara Mar");
// atento: nombre es un string
est3.edad = 23;
printf("%s\n%s\n%s\n", est1.nombre, est2.nombre, est3.nombre);
}
Salida:
Carlos Rodrguez
Jos Vargas
Mara Mar

Arreglos de estructuras
Se definen arreglos como de costumbre:
struct Estudiantes {
.
} est[10];
// forma 1: arreglo de 10 elementos
struct Estudiantes est[2];

// forma 2: arreglo de 2 elementos

struct Estudiantes est[3] = {{123, "Carlos Rodrguez", 25}, {125, "Mara Mar", 23}}; // no se asign valores a est[2].
scanf(%d, &est[2].codigo);

// lee est[2].codigo

est[2].nombre = Juan Juan;


strcpy(est[2].nombre, "Mara Mar");
printf(%s, est[2].nombre);

// Error: nombre es una cadena


// Imprime est[2].nombre

Anidamientos de estructuras
Una estructura puede anidarse dentro de otra, se puede formar una cascada, ejemplo: Defina, lea e imprima datos de una estructura.
Programa 09_02.c:
// Definir, asignar valores e imprimir datos de una estructura con anidamiento
#include <stdio.h>
#include <string.h>
void main(void){
struct Nombres {
// estructura simple
PGINA: 2

Lenguaje C
char nombre[15];
char apellido[15];
};
struct Estudiantes {
// estructura ms compleja que anida
int codigo;
struct Nombres nombre;
// estructura simple anidada
int edad;
} est1 ={123, {"Jos", "Romero"}, 19}, est2;
// define dos variables y asigna valores a la primera
printf("Codigo: "); scanf("%d", &est2.codigo);
printf("Nombre: "); scanf("%s", est2.nombre.nombre);
strcpy(est2.nombre.apellido, "100 Fuegos");
printf("Edad: "); scanf("%d", &est2.edad);
printf("\nReporte\n");
printf("Codigo: %d\n", est2.codigo);
printf("Nombre: %s\n", est2.nombre.nombre);
printf("Apellido: %s\n", est2.nombre.apellido);
printf("Edad: %d\n", est2.edad);
}
Salida:
Codigo: 12
Nombre: Carlos
Edad: 15
Reporte
Codigo: 12
Nombre: Carlos
Apellido: 100 Fuegos
Edad: 15

Apuntadores a estructura
Un apuntador puede apuntar a cualquier tipo de dato, ejemplo:
struct Datos {
int campo1;
char campo2[25];
} dato;
// dato ocupar un rea continua de de 4 + 25 = 29 bytes
Se define un apuntador a la variable dato como de costumbre:
struct Datos *pdato = &dato;
// dato no es un puntero, como sucede con un arreglo, por eso se usa &
Mientras pdato apunte a dato, se cumple:
dato. Campo1 == (*pdato).campo1 == pdato->campo1 // la flecha se escribe: - (menos) seguido de >
Se usa la flecha para hacer menos incmoda la notacin de puntero.
Atento, la instruccin:
if(pdato == &(dato.campo1));
// es true, porque apuntan a la misma direccin
Compila con warning debido a que pdato es un puntero de tipo Dato y &(dato.campo1) es de tipo int; sin embargo el if funciona bien.
Ejemplo: Defina y utilice un apuntador a estructura.
Programa 09_03.c:

// Definir y utilizar un apuntador a estructura.


#include<stdio.h>
#include<string.h>
void main(void){
struct Dato {
int campo1;
char campo2[25];
} dato, *pdato = &dato;
// define dato y *pdato
(*pdato).campo1 = 123;
// asigna valores
strcpy ( pdato->campo2, "hola" );
printf("%d\n", dato.campo1);
printf("%s\n", pdato->campo2);
if(pdato == &(dato.campo1)) printf("El if() funciona\n");
else
printf("El if() no funciona\n");
PGINA: 3

Lenguaje C
}
Salida:
123
hola
El if() funciona

Paso de argumentos de tipo estructura a funciones


Leer y escribir datos de estructuras:
Programa 09_04a.c:
Argumentos:
1) Campos de estructura: lista1
2) Estructura: lista2

Programa 09_04b.c:
Argumento:
3) Arreglo de estructuras: lista

#include<stdio.h>
#define MAX 10
#define LONGE 60
struct Alumnos{
int codigo;
char nombre[LONGE];
};
void leer (int *codigo, char nombre[], struct Alumnos *lista);
void escribir(int codigo, char nombre[], struct Alumnos lista);
void main(void) {
struct Alumnos lista1, lista2;
leer(&lista1.codigo, lista1.nombre, &lista2);
// atento al uso de &
escribir(lista1.codigo, lista1.nombre, lista2);
}
void leer(int *codigo, char nombre[], struct Alumnos *lista) {
printf("Ingrese 2 estructuras\n");
printf("Numero1 : "); scanf("%d", codigo);
printf("Caracter1: ");
while(getchar()!=10);
// para limpiar el buffer
scanf("%s",nombre);
printf("Numero2 : "); scanf("%d", &lista->codigo);
printf("Caracter2: ");
while(getchar()!=10);
// para limpiar el buffer
scanf("%s", lista->nombre);

void leer (struct Alumnos *lista, int *n);


void escribir(struct Alumnos *lista, int n);
void main(void) {
int n;
struct Alumnos lista[4];
leer(lista, &n);
// atento al uso de &
escribir(lista, n);
}
void leer(struct Alumnos *lista, int *n) {
int i; *n = 2;
printf("Ingrese 2 estructuras\n");
for(i=0; i<*n; i++, lista++){
printf("Numero : "); scanf("%d", &lista->codigo);
printf("Caracter: ");
while(getchar()!=10);
// para limpiar el buffer
scanf("%s", lista->nombre);
}
}

}
void escribir(int codigo, char nombre[],struct Alumnos lista) {
printf("-------\ncodigo nombre\n");
printf( "%d\t\%s\n", codigo, nombre);
printf( "%d\t\%s\n", lista.codigo, lista.nombre);
}

void escribir(struct Alumnos *lista, int n){


int i;
printf("-------\nCampo1 Campo2\n");
for(i=0; i<n; i++, lista++)
printf( "%d\t\%s\n", lista->codigo, lista->nombre);
}

Salida:
Campo1: 12
Campo2: Jos
Campo1: 44
Campo2: Carlos
------Campo1 Campo2
12
Jos
44
Carlos

PGINA: 4

Lenguaje C
Ejercicio: Leer, ordenar y escribir arreglo de estructuras:
Programa 09_05a.c:
sin funciones

Programa 09_05b.c:
con funciones

#include<stdio.h>
#define MAX 10
#define LONGE 60
struct Alumnos{
int codigo;
char nombre[LONGE];
};
int leer(struct Alumnos *lista, struct Alumnos **plista);
void ordenar(struct Alumnos *lista, struct Alumnos **plista, int n);
void imprimir(struct Alumnos **plista, int n);
void main(void){
struct Alumnos lista[MAX], *plista[MAX], *pmin;
int n=0, i, j, imin;

void main(void){
struct Alumnos lista[MAX], *plista[MAX];
int n;
n = leer(lista, plista);
ordenar (lista, plista, n);
imprimir(plista, n);
}
int leer(struct Alumnos *lista, struct Alumnos **plista){
int n = 0;

printf ("Teclee Cdigo y Nombre; para finalizar (cdigo = 0):\n");


do {
printf ("Cdigo: "); scanf("%d", &lista[n].codigo);
if(lista[n].codigo == 0) break;

if(lista[n].codigo == 0) return n;

printf ("Nombre: "); scanf("%s", lista[n].nombre);


plista[n] = &lista[n];
n++;
} while (n<MAX);
return n;
}
void ordenar(struct Alumnos *lista, struct Alumnos **plista, int n){
struct Alumnos *pmin;
int i, j, imin;
for(i=0; i<n-1; i++){
// ordenar punteros por nombre
imin = i;
pmin = plista[i];
for(j=i+1; j< n; j++)
if(strcmp(pmin->nombre,lista[j].nombre) > 0){
imin = j;
pmin = plista[j];
}
if(imin > i){
plista[imin] = plista[i];
plista[i] = pmin;
}
}
}
void imprimir(struct Alumnos **plista, int n){
int i;
printf ("\nCdigo Nombre");
for (i=0;i<n;i++)
printf("\n%d\t%s", plista[i]->codigo, plista[i]->nombre);
printf ("\n");
}
}
PGINA: 5

Lenguaje C
Salida:
Teclee Cdigo y Nombre; para finalizar (cdigo = 0):
Cdigo: 10
Nombre: Jos
Cdigo: 12
Nombre: Carlos
Cdigo: 0
Cdigo Nombre
12
Carlos
10
Jos

Unin
Hemos estudiado estructuras, por ejemplo:
struct Ahorro {
int campo1[8];
long campo2[6];
};
El propsito de una estructura es contener todos los campos al mismo tiempo durante la ejecucin de un programa. El espacio de una
estructura es la suma de los espacios de todos los campos.
Una unin tiene una definicin parecida, por ejemplo:
union [Ahorro] {
int campo1[8];
long campo2[6];
} [miAhorro, .];
// variables de tipo union Ahorro
El propsito de una union es ahorrar espacio de memoria, el espacio de una unin es el mximo(campo1. Campo2, ); en tiempo de
ejecucin contendr un solo campo; por ejemplo:
momento campo contenido
1
campo1: asigna valores a campo1 y usa campo1
2
campo2: asignar valores a campo2 y usa campo2,
.
Si en el momento 1 usar el campo2, campo2 no tendra el valor correcto, lo mismo sucede si en el momento 2 usar el campo1. No se
produce error en tiempo de compilacin, es probable que no se produzca error en tiempo de ejecucin; pero los resultados sern
incorrectos. Es responsabilidad del programador que este error lgico (invisible) no suceda.
Referencia a los campos de uniones
La notacin para uniones es parecida a la de estructuras, ejemplo: ejemplo: Defina, lea e imprima datos de una union.
Programa 09_06.c:
// Definir, leer e imprimir datos de una union
#include<stdio.h>
union Ahorro {
int campo1[8];
long campo2[2];
};
// el tamao de esta union es 4 * 8 = 32 bytes
void main(void){
union Ahorro miAhorro, *pmiAhorro;
// define a las variables miAhorro y a pmiAhorro (puntero)
pmiAhorro = &miAhorro;
// pmiAhorro apunta a miAhorro;
miAhorro.campo1[0] = 4;
// asigna valor a campo1[0] = 4
pmiAhorro->campo1[1] = 6;
// asigna valor a campo1[1] = 4
printf("%lu\t %lu\n", pmiAhorro->campo1[0], miAhorro.campo1[1]);
printf("%d\t %d\n", pmiAhorro->campo2[0], miAhorro.campo2[1]); // error lgico.
}
Salida:
4
6
25769803780
4195392
// error lgico: no se haba asignado valor a campo2.

PGINA: 6