Fundamentos de programación

Anuncio
Fundamentos de
programación
Estructuras y Uniones
Estructuras
Una estructura es una forma de agrupar un conjunto
de datos de distinto tipo bajo un mismo nombre o
identificador.
struct [nombre]
{
<tipo> <campo> [,<campo>,…,<campo>];
··· ··· ···
<tipo> <campo> [,<campo>,…,<campo>];
}
La declaración de una estructura crea un nuevo tipo
de datos, cuyo nombre puede ser o no especificado.
Estructuras
Declaraciones
struct complejo
{
double Re, Im;
};
struct complejo z, w, vector[20];
struct persona
{
int dni;
char nombre[20], apellido[50];
char direccion[100];
} persona1, persona2;
struct persona arraypersonas[40];
Estructuras
Declaraciones
struct vehiculo
{
int
precio;
char
marca [20];
char * matricula;
};
struct vehiculo coche, camion, moto;
typedef struct TLista
{
int NElem;
TElem valores [MaxElem];
} TipoLista;
TipoLista Lista, ArrayListas [10];
Estructuras
Acceso a los campos de una estructura
<variable estructura>.<campo>
struct vehiculo coche, camion, moto;
coche.precio = 15500;
memcpy(camion.marca,“RENAULT”,7);
moto.matricula = “3491 CKS”;
for(i = 0; i < 20; i++)
coche.marca[i] = ‘ ’;
scanf(“%d %s”, &coche.precio, coche.marca);
printf(“%s\n”,moto.matricula);
Estructuras
Inicialización de estructuras
struct fecha
{
int
dia;
char * mes;
int
año;
} fiesta = {12, “octubre”, 1991};
struct fecha Fec[2] ={{6, “enero”, 2012},
{4, “marzo”, 2004}};
struct complejo z = {1, 1};
struct complejo w = {0, 1};
TipoLista Lista = {0, {0}};
struct TLista NuevaLista = {4, {6,3,1,9}};
Estructuras
Asignación de estructuras
La sentencia de asignación, a diferencia de arrays, puede
usarse para realizar una copia global de estructuras.
struct fecha
{
int
dia;
char * mes;
int
año;
} Antigua, Nueva;
La sentencia de asignación
Antigua = Nueva;
copia la estructura Nueva en Antigua campo a campo.
Estructuras
Estructuras como retorno de una función
struct Rect
{
double coX, coY;
};
struct Polar
{
double rad, ang;
};
struct Rect polar2rect (struct Polar punto)
{
struct Rect rt;
rt.coX = punto.rad * cos(punto.ang);
rt.coY = punto.rad * sin(punto.ang);
return rt;
}
Estructuras
Estructuras con campos estructura
struct Coordenadas
{
struct Rect rec;
struct Polar pol;
};
struct Coordenadas c, coor[3];
c.rec.coX = 1.0; c.rec.coY = 2.0;
c.pol.rad = 1.5; c.pol.ang = 0.5;
c.rec = polar2rect(c.pol);
coor[0] = c;
coor[1].rec.coX = 1.0;
coor[2].pol.ang = PI/2;
Estructuras
Punteros a estructuras
struct ejemplo
{
int
vp;
char * cadena;
char
vector [4];
};
struct ejemplo A, *ptr;
A.vp = 3; A.cadena = “Hola”; A.vector = {0};
ptr = &A;
printf(“%d\n”, ptr->vp);
printf(“%s\n”, ptr->cadena);
for(j = 0; j < 4; j++) ptr->vector[j] = 8;
Estructuras
Acceso a los campos de un puntero a estructura
(*<variable puntero>).<campo>
<variable puntero> -> <campo>
¾ Los paréntesis son necesarios debido a la mayor prioridad
del operador ‘.’ respecto a ‘*’
¾ La segunda forma de acceso es más compacta y habitual.
struct ejemplo * ptr;
(*ptr).vp;
(*ptr).cadena[0];
(*ptr).vector;
*(*ptr).cadena;
&(*ptr).vector[j];
ptr->vp;
ptr->cadena[0];
ptr->vector;
*ptr->cadena;
&ptr->vector[j];
Estructuras
Acceso a los campos de un puntero a estructura
struct {
int
num;
char * cad;
} *ptr;
++ptr->num
(++ptr)->num
(ptr++)->num
ptr++->num
*ptr->cad
*ptr->cad++
(*ptr->cad)++
*ptr++->cad
:
:
:
:
:
:
:
:
Incrementa num, no ptr.
Incrementa ptr antes de acceder a num.
Accede a num y después incrementa ptr.
Lo mismo que lo anterior.
Accede al contenido del puntero cad.
Accede al contenido de cad y después incrementa cad.
Aumenta el valor del contenido de cad en una unidad.
Incrementa ptr tras acceder al contenido del punt. cad.
Estructuras
Funciones y parámetros de salida con estructuras
struct registro
{
int
valor;
char cadena [6];
int
vector [4];
};
void LeerRegistro (struct registro * Reg)
{
int j;
scanf(“%d”, &Reg->valor);
for(j = 0; j < 6; j++)
scanf(“%c”, &Reg->cadena[j]);
for(j = 0; j < 4; j++)
scanf(“%d”, &Reg->vector[j]);
}
Estructuras
Funciones y parámetros de salida con estructuras
void main ( )
{
int j;
struct registro info;
void LeerRegistro (struct registro *);
do
LeerRegistro(&info);
while(info.valor < 0);
printf(“%d\n”,info.vector[0]);
for(j = 1; j < 4; j++) {
info.vector[j] += info.vector[0];
printf(“%d\n”, info.vector[j]);
}
}
Estructuras
Tamaño de una estructura
En general el tamaño (en bytes) de una estructura no tiene
por qué coincidir con la suma del tamaño de sus campos.
Por ejemplo, si asumimos que el tamaño de un char es un
byte y que un int ocupa cuatro bytes, la estructura
struct campos {
char car;
int ent;
};
puede requerir ocho bytes en vez de cinco. Esto se debe
al alineamiento de variables en C. En estos casos hay que
utilizar el operador sizeof, sizeof(struct campos).
Uniones
Una unión es una variable que puede tener (en distintos
instantes) objetos de diferentes tipos y tamaños. Estas
variables proporcionan una forma de manejar clases de
datos diferentes, pero que se ubican en una misma área
de memoria.
union [nombre]
{
<tipo> <campo>;
··· ··· ···
<tipo> <campo>;
}
Uniones
La unión debe tener el suficiente tamaño para almacenar
el campo más largo. El tamaño total dependerá de la
máquina donde se realice la implementación.
union UClase
{
char
*svalor;
long int ivalor;
} Clase;
Supongamos que sizeof Clase == 4. El tratamiento
de estos cuatro bytes está condicionado al campo con que
se accede a la unión.
Uniones
El acceso a los campos de una unión se realiza de igual
forma que las estructuras. Ahora, si tenemos en cuenta
que los campos de las uniones comparten el mismo
área de memoria, ¿qué salida nos podemos esperar al
ejecutar estas sentencias?
Clase.svalor = “ABC”;
printf(“%s\n”,
printf(“%ld\n”,
printf(“%ld\n”,
printf(“%p\n”,
printf(“%lx\n”,
Clase.svalor);
Clase.ivalor);
Clase.svalor);
Clase.svalor);
Clase.ivalor);
Uniones
¾ Los accesos a los campos de una unión y/o
puntero a unión se hacen de la misma forma que
una estructura y/o puntero a estructura.
¾ Los campos de una unión comparten una
misma área de memoria.
¾ Una unión sólo puede ser inicializada con un
valor del tipo de su primer campo.
¾ La sentencia de asignación puede usarse para
copiar uniones que tengan la misma definición.
Uniones con campos de bits
union byte {
unsigned char b;
struct {
unsigned int
unsigned int
unsigned int
unsigned int
unsigned int
unsigned int
unsigned int
unsigned int
} bits;
struct {
unsigned int
unsigned int
} nibbles;
};
bit8:1;
bit7:1;
bit6:1;
bit5:1;
bit4:1;
bit3:1;
bit2:1;
bit1:1;
nibble2:4;
nibble1:4;
Descargar