Sei sulla pagina 1di 7

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.
struct Estudiante { // Define la estructura Estudiante
int codigo;
char nombre[25];
int edad;
};
// Definicin de variables de tipo estructura y asignacin de valores. En modo similar que para variables simples:
int estudx = 0;
struct Estudiante estud1 = {1, Juan Carlos, 25};

La sintaxis de una estructura es un poco ms elaborada que el ejemplo anterior:


Sintaxis de una estructura:
struct [MiStru] { // Atento a la notacin camello
tipo1 campo1;
tipo2 campo2;
.....
} [miStru1, miStru2, .]; // Declaracin de variables de tipo struct MiStru. Note las partes [opcionales]
// Cada variable miStru.. ocupa un rea continua de longitud = longitud de campo1 + longitud de campo2 + ...
Donde:
MiStru es el nombre de la estructura
miDato1, miDato2, . son variables del tipo struct MiStru.
No tiene sentido omitir las dos partes opcionales:
struct {
tipo1 campo1;
.....
};
Si la estructura no tiene nombre, no puede ser utilizada ms adelante.

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.

Admrate, algrate !!!! Estamos usando magistralmente un principio fundamental de integracin universal que lo usan todas las
ciencias, la gestin y el sentido comn. Practcalo y aplcalo.

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, coraje, 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 Estudiante {
int codigo;
char nombre[25];
} est1, . ; // forma 1

struct Estudiante est2, ...; // forma 2.


PGINA: 1
Lenguaje C

struct Estudiante est3 = {124, "Jos Vargas"}; // define y asigna valores

est1.codigo = 123; // asina valor a la variable est1.codigo


strcpy(est1.nombre, "Mara Mar"); // asina valor a la cadena est1.nombre

scanf(%d, &est1.codigo); // lee un entero


scanf(%s, est1.nombre); // lee una cadena
printf(%d, est1.codigo);
printf(%s, est1.nombre);

Ejemplo:
struct {
int codigo;
char nombre[25];
int edad;
} est1, est2, est3; // define las variables est1 y est2 de tipo Estudiante.

La definicin anterior es equivalente a:


struct Estudiante { // define la estructura
int codigo, edad;
char nombre[25];
};
struct Estudiante est1, est2, est3; // define las variables est1 y est2 de tipo Estudiante.

// 09_01.c : Definir, asignar valores e imprimir datos de una estructura


#include<stdio.h>
#include<string.h>
void main(void){
struct Estudiante {
int codigo;
char nombre[25];
int edad;
} est1 = {123, "Carlos Rodrguez", 25}; // asigna valores a est1
struct Estudiante 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 Estudiante {
.
} est[10]; // forma 1: arreglo de 10 elementos

struct Estudiantes est[2]; // forma 2: arreglo de 2 elementos

struct Estudiante 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; // Error: nombre es una cadena


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

PGINA: 2
Lenguaje C
Anidamientos de estructuras
Una estructura puede anidarse dentro de otra, se puede formar una cascada, ejemplo: Defina, lea e imprima datos de una estructura.

// 09_02.c : Definir, asignar valores e imprimir datos de una estructura con anidamiento
#include <stdio.h>
#include <string.h>
void main(void){
struct Nombre { // estructura simple
char nombre[15];
char apellido[15];
};
struct Estudiante { // estructura ms compleja que anida
int codigo;
struct Nombre 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

Apuntador a estructura
Apuntador a estructura
Un apuntador puede apuntar a cualquier tipo de variable, en particular a una de tipo estructura. Sea:
struct MiStru {
int campo1; // 4 bytes
char campo2[25]; // 25 bytes
};
struct MiStru miStru, *pmiStru = &miStru; // Atento se usa &, a diferencia de apuntador a arreglo.

Mientras pmiStru apunte a miStru, se cumplen las siguientes equivalencias:


miStru.Campo1 == (*pmiStru).campo1 == pmiStru->campo1
Se usa la flecha para hacer menos incmoda la notacin de puntero, se escribe: - (menos) seguido de >

Atento, la instruccin:
if( pmiStru == &(miStru.campo1)); // es true, porque son la misma direccin
Pero, compila con warning debido a que pmiStru es un puntero a tipo MiStru y &(miStru .campo1) es puntero de tipo int;
sin embargo. El casting automtico funciona y se ejecuta bien.

// 09_03.c : Define y utiliza un apuntador a estructura


#include<stdio.h>
#include<string.h>
void main(void){
struct Dato {
int campo1;
char campo2[25];

PGINA: 3
Lenguaje C
} 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");
}
Salida:
123
hola
El if() funciona

Paso de argumentos de tipo estructura a funciones


/* 09_04a.c : Leer y escribir estructuras con parmetros: /* 09_04b.c : Leer y escribir estructuras con parmetro:
Campos de estructura: lista1 Arreglo de estructuras: lista
Estructura: lista2
*/ */
#include<stdio.h>
#define MAX 10
#define LONGE 60
struct Alumno{
int codigo;
char nombre[LONGE];
};
void leer (int *codigo, char nombre[], struct Alumno *lista); void leer (struct Alumno *lista, int *n);
void escribir(int codigo, char nombre[], struct Alumno lista); void escribir(struct Alumno *lista, int n);
void main(void) { void main(void) {
int n;
struct Alumno lista1, lista2; struct Alumno lista[2];
leer(&lista1.codigo, lista1.nombre, &lista2); // atento al & leer(lista, &n); // atento al &
escribir(lista1.codigo, lista1.nombre, lista2); escribir(lista, n);
} }
void leer(int *codigo, char nombre[], struct Alumno *lista) { void leer(struct Alumno *lista, int *n) {
int i; *n = 2;
printf("Ingrese 2 estructuras\n"); printf("Ingrese 2 estructuras\n");
printf("Numero1 : "); scanf("%d", codigo);
printf("Caracter1: ");
while(getchar()!=10); // para limpiar el buffer
scanf("%s",nombre); for(i=0; i<*n; i++, lista++){
printf("Numero2 : "); scanf("%d", &lista->codigo); printf("Numero : "); scanf("%d", &lista->codigo);
printf("Caracter2: "); printf("Caracter: ");
while(getchar()!=10); // para limpiar el buffer while(getchar()!=10); // para limpiar el buffer
scanf("%s", lista->nombre); scanf("%s", lista->nombre);
} }
}
void escribir(int codigo, char nombre[],struct Alumno lista) { void escribir(struct Alumno *lista, int n){
int i;
printf("-------\ncodigo nombre\n"); printf("-------\nCampo1 Campo2\n");
printf( "%d\t\%s\n", codigo, nombre); for(i=0; i<n; i++, lista++)
printf( "%d\t\%s\n", lista.codigo, lista.nombre); 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

/* 90_05a.c : Leer, ordenar y escribir arreglo de estructuras /* 90_05b.c : Leer, ordenar y escribir arreglo de estructuras con
sin funciones funciones
*/ */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 10
#define LONGE 60
struct Alumno{
int codigo;
char nombre[LONGE];
int nota;
};
int leer(struct Alumno *lista, struct Alumno **plista);
void ordenar(struct Alumno *lista, struct Alumno **plista, int n, int k);
void imprimir(struct Alumno **plista, int n);
void main(void){ void main(void){
struct Alumno lista[MAX], *plista[MAX], *pmin; struct Alumno lista[MAX], *plista[MAX];
int n=0, i, j, imin; int n;
printf("Datos cargados");
n = leer(lista, plista);
imprimir(plista, n); // antes de ordenar
printf("\nOrdenar por Nombre");
ordenar (lista, plista, n, 1);
imprimir(plista, n); // despus de ordenar
printf("\nOrdenar por Nota");
ordenar (lista, plista, n, 2);
imprimir(plista, n); // despus de ordenar
}
int leer(struct Alumno *lista, struct Alumno **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);
printf ("Nota : "); scanf("%d", &lista[n].nota);
plista[n] = &lista[n];
n++;
} while (n<MAX);
return n;
}
void ordenar(struct Alumno *lista, struct Alumno **plista, int n, int k){
struct Alumno *pmin;
int i, j, imin, ik;
for(i=0; i<n-1; i++){
imin = i;
pmin = plista[i];
for(j=i+1; j< n; j++) for(j=i+1; j< n; j++) {
if(k==1) ik = strcmp(pmin->nombre,plista[j]->nombre);
if(k==2) ik = pmin->nota > plista[j]->nota;
if(strcmp(pmin->nombre,plista[j]->nombre)>0){ if(ik>0){
imin = j; imin = j;
pmin = plista[j]; pmin = plista[j];
} }
}

PGINA: 5
Lenguaje C
if(imin > i){
plista[imin] = plista[i];
plista[i] = pmin;
}
}
}
printf("\nOrdenar por Nombre"); void imprimir(struct Alumno **plista, int n){
int i;
printf ("\nCdigo Nombre Nota");
for (i=0;i<n;i++)
printf("\n%d\t%s\t%d", plista[i]->codigo, plista[i]->nombre, plista[i]->nota);
printf ("\n");
}
}
Salida:
Teclee Cdigo y Nombre; para finalizar (cdigo = 0):
Cdigo : 10
Nombre: Jos
Nota : 15
Cdigo : 20
Nombre: Carlos
Nota : 16
Cdigo : 30
Nombre: Abel
Nota : 14
Cdigo: 0
Cdigo Nombre Nota
10 Jos 15
20 Carlos 16
30 Abel 14
Ordenar por Nombre
Cdigo Nombre Nombre
30 Abel 14
20 Carlos 16
10 Jos 15
Ordenar por Nota
Cdigo Nombre Nota
30 Abel 14
10 Jos 15
20 Carlos 16

PGINA: 6
Lenguaje C
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.

Definicin, asignacin y uso de los campos de union


La notacin para uniones es parecida a la de estructuras, ejemplo:
// 09_06.c : Definir, leer e imprimir datos de una unin
#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: 7

Potrebbero piacerti anche