transparencias de Estructuras

Anuncio
Fundamentos de Informática
1
2
Introducción
„
Nos permiten agrupar valores de tipos diferentes en una misma variable (tipo
compuesto).
{
{
{
„
Declaración de tipos de estructuras
„
Para declarar un nuevo tipo de estructura se utiliza la siguiente sintaxis:
struct nombre_estructura {
declaración del campo_1;
declaración del campo_2;
...
Una estructura se divide en campos.
Cada campo puede ser de cualquier tipo.
Cada campo de la estructura se identifica por un nombre.
declaración del campo_N;
Nos permiten crear nuevos tipos de datos en C (tipos definidos por el usuario).
{
{
„
„
{
};
Podemos definir diferentes tipos de estructuras en nuestro programa.
Al definir una estructura, se especifica:
„
Los campos se declaran
igual que las variables
El número de campos.
El nombre de los campos.
El tipo de los campos.
Con la declaración anterior se define un nuevo tipo de datos llamado:
Cada tipo de estructura definido pasa a ser un nuevo tipo de datos que podemos
utilizar para declarar variables.
struct nombre_estructura
Se pueden declarar variables del nuevo tipo definido.
3
4
Declaración de tipos de estructuras: ejemplo
struct complejo {
double real;
double imag;
};
real
Definimos un nuevo tipo de datos llamado
struct complejo formado por dos campos de
tipo double llamados real e imag
„
.
imag
apellidos[80]
Podemos declarar variables del nuevo tipo de estructura en la propia declaración
de la estructura:
struct nombre_estructura {
...
} variable ;
Definimos un nuevo tipo de datos llamado
struct empleado formado por los siguientes
campos:
struct empleado {
char nombre[40];
char apellidos[80];
int edad;
.
};
nombre[40]
Declaración de variables
„
También podemos declarar las variables en una declaración independiente:
™ nombre (cadena de 40 caracteres)
™ apellidos (cadena de 80 caracteres)
struct nombre_estructura variable ;
™ edad (de tipo entero)
edad
La estructura struct nombre_estructura debe haber
sido declarada previamente en el código.
ATENCIÓN: en los ejemplos anteriores no se han declarado variables, sólo se han creado
dos nuevos tipos de datos llamados struct complejo y struct empleado.
Dpto. de ATC, Universidad de Sevilla - Página 1 de 9
Fundamentos de Informática
5
Declaración de variables: ejemplo
Declaración de variables con inicialización
secretario
struct complejo {
double real;
double imag;
};
nombre[40]
6
struct nombre_estructura variable = {valor, valor, ... };
apellidos[80]
edad
Por cada campo de la estructura debe aparecer un
valor. Los valores se asignan en el mismo orden en que
se han declarado los campos dentro de la estructura.
director
struct empleado {
char nombre[40];
char apellidos[80];
int edad;
} director;
nombre[40]
apellidos[80]
edad
Ejemplo:
Las variables director y
secretario son de tipo
struct empleado.
struct polinomio {
unsigned grado;
double coeficientes[10];
};
struct complejo {
double real;
double imag;
};
Las variables x e y son de
tipo struct complejo.
struct empleado secretario;
struct complejo x, y;
struct polinomio parabola;
Valor del campo real
Valor del campo imag
x
struct complejo x = {3.56, -1};
real 3.56
imag -1
La variable parabola es de
tipo struct polinomio.
7
Acceso a los campos
Declaración de variables con inicialización: ejemplo
struct empleado {
char nombre[40];
char apellidos[80];
int edad;
};
8
nombre_variable.nombre_campo
El nombre de la variable y del campo
se separan por el carácter ‘.’
El campo coeficientes es un
vector, por lo tanto sus valores
deben aparecer entre llaves.
struct polinomio {
unsigned grado;
double coeficientes[10];
};
Ejemplo:
struct complejo {
double real;
double imag;
};
struct polinomio pol = {2, {-1, 5, 2} };
struct empleado director = {“Ana”, “Raya”, 18 };
.
real
x
imag
real
y
imag
real
imag
x real 3.56
imag -1
director
pol
0
grado 2
coeficientes -1
0
5
2
...
1
2
...
9
1
2
3
...
nombre A
n
a
\0
...
apellidos R
a
y
a
\0
edad 18
39
...
...
79
struct complejo x = {3.56, -1};
struct complejo y;
y.real = x.real + 1;
y.imag = 0;
Dpto. de ATC, Universidad de Sevilla - Página 2 de 9
y real 4.56
imag 0
Fundamentos de Informática
9
10
Acceso a los campos: ejemplo 1a
struct complejo {
double real;
double imag;
};
Acceso a los campos: ejemplo 1b
struct complejo {
double real;
double imag;
};
p
grado 2
coeficientes 4
1
0
1
struct polinomio {
unsigned grado;
double coeficientes[10];
};
2.1
...
2
...
y
real
4
1
0
1
2.1 ...
2
...
x
real
9
7.2
imag
y
real
x.real = 3.1 * p.grado + p.coeficientes[1];
imag
y.imag = x.real + 2.34;
2
main() {
struct polinomio p = {2, {4,1,2.1} };
struct complejo x, y;
imag
x.real = 3.1 * p.grado + p.coeficientes[1];
grado
coeficientes
struct polinomio {
unsigned grado;
double coeficientes[10];
};
9
x
real
main() {
struct polinomio p = {2, {4,1,2.1} };
struct complejo x, y;
p
imag
y.imag = x.real + 2.34;
scanf( “%lf”, &x.imag );
scanf( “%lf”, &x.imag );
if (p.coeficientes[0] > y.real – 2) {
...
if (p.coeficientes[0] > y.real – 2) {
...
11
12
Acceso a los campos: ejemplo 1c
struct complejo {
double real;
double imag;
};
Operador de asignación
„
p
grado
2
coeficientes
4
1
0
1
struct polinomio {
unsigned grado;
double coeficientes[10];
};
main() {
struct polinomio p = {2, {4,1,2.1} };
struct complejo x, y;
x.real = 3.1 * p.grado + p.coeficientes[1];
„
2.1 ...
2
x
real
...
7.2
imag
y
real
imag 9.54
9
Al igual que ocurre con los tipos básicos (int, float, double, ...), se pueden
realizar asignaciones entre variables del mismo tipo de estructura.
Ejemplo:
fx
struct polinomio {
unsigned grado;
double coeficientes[3];
};
main() {
struct polinomio fx = {2, {4,0,-1}};
struct polinomio pol;
pol = fx;
}
grado
2
coeficientes
4
0
-1
0
1
2
0
1
2
pol
grado
coeficientes
y.imag = x.real + 2.34;
scanf( “%lf”, &x.imag );
if (p.coeficientes[0] > y.real – 2) {
...
pol
fx
grado
grado
2
coeficientes
4
0
-1
0
1
2
Dpto. de ATC, Universidad de Sevilla - Página 3 de 9
Se copian
los valores coeficientes
2
4
0
-1
0
1
2
Fundamentos de Informática
13
14
Estructuras y funciones (1)
„
„
Estructuras y funciones (2)
Las funciones pueden devolver valores de tipo estructura.
Ejemplo:
„
struct punto {
float x, y;
};
struct punto crea_punto( float, float );
„
void main() {
struct punto s;
3
struct punto {
float x, y;
};
float modulo( struct punto );
El valor devuelto se
copia en s
s
s = crea_punto( -3, 2 );
x
-3
y
2
void main() {
struct punto s = {0,-2};
printf( “%f\n”, modulo( s ) );
}
1
}
Los parámetros de tipo estructura se pasan por valor: en la llamada a la función,
el valor de la estructura se copia en el parámetro.
Ejemplo:
Se ejecuta la función
struct punto crea_punto( float cx, float cy ) {
struct punto aux;
aux.x = cx;
aux.y = cy;
return aux;
}
2
-3
y
2
p se inicializa con el
valor de s
float modulo( struct punto p ) {
return sqrt( p.x * p.x + p.y * p.y );
}
La función devuelve
el valor de aux:
x
s
p
x
0
y
-2
x
0
y
-2
Ejecución del 2
programa:
15
Estructuras y funciones: ejemplo 1a
16
Estructuras y funciones: ejemplo 1b
En este ejemplo se muestran un conjunto de funciones y estructuras de datos para
manipular números complejos.
Devuelve la suma de los
complejos a y b.
#include <stdio.h>
struct cmplj {
double real;
double imag;
};
struct cmplj crea_c( double r, double i ) {
struct cmplj aux;
aux.real = r;
aux.imag = i;
return aux;
}
void impr_c( struct cmplj c ) {
printf( “(%lf + %lfi)”, c.real, c.imag );
}
Las variables de tipo struct cmplj
contienen números complejos.
Crea y devuelve un
complejo con la parte
real igual a r y la parte
imaginaria igual a i.
Muestra por pantalla
el complejo c.
struct cmplj sum_c ( struct cmplj a, struct cmplj b ) {
struct cmplj aux;
aux.real = a.real + b.real;
aux.imag = a.imag + b.imag;
return aux;
}
Devuelve el producto de
los complejos a y b.
struct cmplj mul_c ( struct cmplj a, strucr cmplj b ) {
struct cmplj aux;
aux.real = a.real * b.real – a.imag * b.imag;
aux.imag = a.real * b.imag + a.imag * b.real;
return aux;
}
Continúa...
Dpto. de ATC, Universidad de Sevilla - Página 4 de 9
Fundamentos de Informática
17
Estructuras y funciones: ejemplo 1c
18
Estructuras y funciones: ejemplo 1d
A continuación mostramos un pequeño programa que muestra por pantalla el resultado
de la expresión 4x2+1, siendo x un número complejo cualquiera. El programa utiliza las
funciones mostradas en las transparencias anteriores.
Veamos paso a paso la sentencia del código anterior que realiza el cálculo:
resultado = sum_c( mul_c( crea_c(4,0), mul_c(x,x) ), crea_c(1,0) );
x
real 2
x2
(4,0)
imag 1
resultado = sum_c( mul_c(
resultado
real
Ejecución del
programa:
real 3
,
imag 4
4x2
main() {
imag
struct cmplj x = {2,1};
struct cmplj resultado;
resultado = sum_c( mul_c( crea_c(4,0), mul_c(x,x) ), crea_c(1,0) );
impr_c( resultado );
}
real 4
imag 0
(1,0)
real 12
resultado = sum_c(
), crea_c(1,0) );
imag 16
,
real 1
);
imag 0
4x2+1
(13 + 16i)
resultado =
real 13
;
imag 16
19
Estructuras y funciones: ejemplo 2a
20
Estructuras y funciones: ejemplo 2b
En este ejemplo se muestra una estructura que contiene datos de empleados de una
empresa y dos funciones que realizan operaciones de este tipo de estructuras.
Lee del teclado los datos de un empleado y
devuelve un valor de tipo struct empleado
con los datos leidos.
#include <stdio.h>
struct empleado {
char nombre[80];
char apellidos[100];
unsigned int dni;
char letra_nif;
};
Las variables de tipo struct empleado
contienen los datos de un empleado.
Muestra por pantalla los datos del empleado
contenidos en el parámetro e.
void impr_empl( struct empleado e ) {
printf( “NOMBRE:%s, %s\nDNI: %u%c\n”, e.apellidos, e.nombre,
e.dni, e.letra_nif );
}
struct empleado lee_empl() {
struct empleado aux;
printf( “Escribe el nombre: “ );
scanf( “%s”, aux.nombre );
printf( “Escribe los apellidos: “ );
gets( “%s”, aux.apellidos );
printf( “Escribe el DNI: “ );
scanf( “%u”, &aux.dni );
scanf( “%c”, &aux.letra_nif );
return aux;
}
Continúa...
Dpto. de ATC, Universidad de Sevilla - Página 5 de 9
Fundamentos de Informática
21
22
Estructuras y funciones: ejemplo 2c
Estructuras anidadas: ejemplo 1a
A continuación se muestra como se pueden utilizar las funciones anteriores para leer e
imprimir por pantalla los datos de un empleado.
main() {
struct empleado var;
var = lee_empl();
printf( “\nEMPLEADO:\n“ );
printf( “*********\n“ );
impr_empl( var );
}
„
„
Ejemplo de ejecución del programa:
Escribe el nombre: Pedro
Escribe los apellidos: Vargas Vargas
Escribe el DNI: 54112112A
EMPLEADO:
*********
NOMBRE: Vargas Vargas, Pedro
DNI: 54112112A
Se pueden declarar estructuras que contienen a otras estructuras.
Ejemplo:
em
hoy
struct fecha {
dia
1
int dia, mes, anio;
mes
1
};
anio 2005
struct empleado {
unsigned dni;
struct fecha nac;
struct fecha alta;
};
main() {
struct fecha hoy = {1,1,2005};
struct empleado em
= {45112112, {25,1,1990}, {1,10,2004}};
em.nac.dia = 9;
em.alta = hoy;
printf( “%d”, em.alta.anio );
}
dni
45112112
nac
mes
1
anio
1990
dia
alta
25
dia
1
mes
10
anio
2004
23
24
Estructuras anidadas: ejemplo 1b
Vectores de estructuras: ejemplo
„
struct fecha {
int dia, mes, anio;
};
struct empleado {
unsigned dni;
struct fecha nac;
struct fecha alta;
};
dni
em
nac
alta
2005
Ejecución del
programa:
9
mes
1
anio
1990
dia
main() {
struct fecha hoy = {1,1,2005};
struct empleado em
= {45112112, {25,1,1990}, {1,10,2004}};
em.nac.dia = 9;
em.alta = hoy;
printf( “%d”, em.alta.anio );
}
struct fecha {
int dia, mes, anio;
};
struct empleado {
char nombre[30];
struct fecha alta;
};
45112112
dia
1
mes
1
anio
2005
Accedemos al campo anio del
campo alta de em
dia
1
hoy mes
1
anio 2005
Vector de 2 elementos de tipo struct empleado
Valor inicial de plantilla[0]
Valor inicial de plantilla[1]
struct empleado plantilla[2] = { {“Lisa”, {12,5,1990}},
{“Bart”, {11,10,1985}}
„
La variable hoy se copia en el
campo alta de em
Se pueden declarar vectores de estructuras, por ejemplo:
Veamos algunos ejemplos de uso de vectores de estructuras:
struct fecha hoy = {31,1,2005};
strcpy( plantilla[1].nombre, “Juan” );
plantilla[1].alta.mes = plantilla[1].alta.dia + 2;
plantilla[0].alta = hoy;
plantilla[0].alta = plantilla[1].alta;
plantilla[1] = plantilla[0];
Dpto. de ATC, Universidad de Sevilla - Página 6 de 9
};
Accedemos al
campo día del
campo alta de
plantilla[1]
Fundamentos de Informática
25
Matrices de estructuras: ejemplo
26
Estructuras complejas: ejemplo 1a
El siguiente ejemplo muestra un ejemplo de una posible estructura para manipular polinomios de
coeficientes complejos y un ejemplo de una función que trabaja con dicha estructura:
También podemos declarar matrices de estructuras.
„ Ejemplo:
Matriz de 2x2 elementos de tipo struct cmplj
„
#define MAX 10
Las variables de tipo struct polinomio_cmplj
contienen polinomios de coeficientes complejos.
struct cmplj {
double real, imag;
};
La función suma_coef suma
los coeficientes del polinomio
struct polinomio_cmplj {
contenido en el parámetro p y
int grado;
devuelve la suma calculada.
struct cmplj coef[MAX];
};
struct cmplj suma_coef( struct polinomio_cmplj p ) {
struct cmplj res = {0,0};
int i;
Accedemos al campo imag del
for (i=0; i<=p.grado; i++) {
elemento de índice i del campo
res.imag = res.imag + p.coef[i].imag;
coef de la estructura p.
res.real = res.real + p.coef[i].real;
}
return res;
}
Continúa...
struct cmplj {
double real, imag;
};
Valor inicial de m[0][0]
main() {
struct cmplj m[2][2] = { {1,0}, {0,4}, {-3,1}, {5,5} };
struct cmplj p[9][15];
p[0][0] = m[1][1];
p[0][1].real = m[0][1].real + m[0][1].imag;
}
Matriz de 9x15 elementos de
tipo struct cmplj
27
Estructuras complejas: ejemplo 1b
Estructuras complejas: ejemplo 2
El siguiente programa muestra cómo podemos utilizar las estructuras y funciones anteriores.
main() {
struct polinomio_cmplj pol = { 3, {{1,2}, {0,1}, {-10,3}} };
struct cmplj res;
res = suma_coef( pol );
}
grado
-9
imag
6
Ejemplos
de acceso
a campos
coef
3
real 1
real 0
imag 2
imag 1
0
pol.coef[1].imag
1
real -10
imag 3
2
real
...
...
A continuación se muestra un ejemplo de una función que calcula el valor de un polinomio de
coeficientes complejos.
struct polc {
int grado;
struct cmplj coef[10];
};
pol
res
real
28
imag
9
El tipo struct cmplj y la función crea_c están definidas en
la transparencia “Estructuras y funciones: ejemplo 1a”
struct cmplj evalua_polc( struct polc p, double x ) {
int i;
struct cmplj res = crea_c (0,0);
double pot_x = 1;
for (i=0; i<=grado; i++) {
res = sum_c( res, mul_c( p.coef[i], crea_c(pot_x,0) );
pot_x = pot_x * x;
}
return res;
}
pol.coef[9].real
Las funciones sum_c y mul_c están definidas en la
transparencia “Estructuras y funciones: ejemplo 1b”
Dpto. de ATC, Universidad de Sevilla - Página 7 de 9
Fundamentos de Informática
29
30
Punteros a estructuras: ejemplo 1a
struct polinomio {
int grado;
double coef[10];
};
Punteros a estructuras: ejemplo 1b
struct polinomio {
int grado;
double coef[10];
};
grado
coef
...
0
1
2
3
...
9
main() {
struct polinomio v1 = {2, {-2, 0.1, 5.3}};
struct polinomio v2;
p apunta a la variable v2
struct polinomio *p;
int *g;
Asignamos v1 a la variable apuntada por p
p = &v2;
(v1 se copia en v2).
*p = v1;
(*p).grado = 3;
Asignamos 3 al campo grado de la variable
(*p).coef[3] = 100;
apuntada por p (asignamos 3 a v2.grado).
g = &(v1.grado);
v2
v2.coef[5] = *g;
grado 3
g = &((*p).grado);
*g = 0;
coef -2 0.1 5.3 100 ...
}
0
1
2
3
...
9
main() {
struct polinomio v1 = {2, {-2, 0.1, 5.3}};
struct polinomio v2;
struct polinomio *p;
int *g;
p = &v2;
*p = v1;
g apunta al campo grado de v1
(*p).grado = 3;
(*p).coef[3] = 100;
Accedemos al campo grado de v1
g = &(v1.grado);
v2.coef[5] = *g;
g = &((*p).grado);
g apunta al campo grado de v2
*g = 0;
}
Asignamos 0 al campo grado de v2
31
32
Punteros a estructuras: ejemplo
Estructuras y ficheros: ejemplo 1a
En el siguiente ejemplo se muestra una función que lee del teclado un número complejo y lo
guarda en la estructura de tipo struct cmplj que se le pasa por referencia.
struct cmplj {
double real, imag;
};
void scan_cmplj( struct cmplj *c ) {
scanf( “%lf”, &(*c).real );
scanf( “%lf”, &(*c).imag );
}
void main() {
struct cmplj x;
printf( “Escribe los valores real e imaginarios: “ );
scan_cmplj( &x );
}
„
„
Cuando se trabaja con ficheros organizados en registros, es útil utilizar estructuras para
contener los datos de los registros.
Ejemplo: A continuación se muestra una posible solución al problema propuesto en la
transparencia del tema de ficheros “Tratamiento secuencial: ejemplo 2a”. Los registros del
fichero “temp.txt” se implementan con una estructura y se define una función para leer un
registro de dicho fichero.
#include <stdio.h>
struct sensor {
char nombre;
int temp;
};
Las variables de tipo struct sensor
contienen los valores de un registro
del fichero “temp.txt”.
void lee_registro( FILE* f, struct sensor *r ) {
char aux;
fscanf( f, “%c”, &(*r).nombre );
fscanf( f, “%d”, &(*r).temp );
fscanf( f, “%c”, &aux );
}
Continúa...
Dpto. de ATC, Universidad de Sevilla - Página 8 de 9
Fundamentos de Informática
33
Estructuras y ficheros: ejemplo 1b
main() {
FILE *ftemp, *fsal;
struct sensor reg;
ftemp = fopen( “c:\\dir\\temp.txt”, “rt” );
fsal = fopen( “c:\\dir\\temp_a.txt”, “wt” );
if (ftemp != NULL && fsal != NULL) {
lee_registro( ftemp, &reg );
while (!feof(ftemp)) {
if (reg.nombre == ‘A’) {
fprintf( fsal, “%d\n”, reg.temp );
}
lee_registro( ftemp, &reg );
}
fclose( ftemp );
fclose( fsal );
}else {
printf( “ERROR\n” );
if (ftemp != NULL)
fclose(ftemp);
}
}
Dpto. de ATC, Universidad de Sevilla - Página 9 de 9
Descargar