07 - Tipos de datos definidos por el programador en lenguaje C: struct, typedef, union

Post on 25-Dec-2014

151 views 2 download

description

Si quiere descargar la presentación y los códigos fuente, dirijase a: http://programaciondecomputadoresunalmzl.wikispaces.com/codigos_y_diapositivas Le agradecería si me reporta los errores que encuentre en la diapositiva (daalvarez arroba unal punto edu punto co)

Transcript of 07 - Tipos de datos definidos por el programador en lenguaje C: struct, typedef, union

1

07 - Tipos de datos definidos por el programador

Diego Andrés Alvarez MarínProfesor Asociado

Universidad Nacional de ColombiaSede Manizales

2

Temario● Definición de tipos (typedef)● Estructuras (struct)● Uniones (union)● Enumeraciones (enum)● Campos de bits

3

typedefSe utiliza para asignar nombres (alternos) a los tipos de datos. La forma general de uso de este comando es:

Ejemplo:

El standard POSIX (http://en.wikipedia.org/wiki/POSIX) solicita que el nombre de un typedef no termine en _t, ya que ellos lo usan en sus declaraciones (recuerde a clock_t, size_t).

4

Enumeraciones

Es un tipo de dato especial que sirve para guardar constantes enteras y asignarles un nombre.

0 1 2

3 4 5 6

6 7 8 14

-5 -4 -3

5

Declaración de variables tipo enum

6

7

enum + switch + warning

No hay default, ni una opción para Guardar ni para Cerrar

8

Utilizando enumeraciones en un ciclo for

9

Estructuras (struct)Una estructura es un conjuto de variables de diferentes tipos relacionadas bajo un mismo nombre

10

Declaración de variables tipo struct

11

Inicialización de estructuras

(gcc GNU extension)

12

Inicialización de arreglos de estructuras

13

Accediendo a los miembros de una estructura

Usando el operador punto “.”

Utilizando punteros: el operador flecha

“->”(NOTA: ver definiciones de struct punto y struct circulo en las diapositivas anteriores)

14

Ejemplo con estructuras

Ver:http://programaciondecomputadoresunalmzl.wikispaces.com/file/detail/07_struct.c

15

Compound literals

Note que p1 y p2 no se inicializaron; en la líneas 15 y 16 se está separando y a la vez asignando el espacio de memoria para p1 y p2 respectivamente. Esta asignación sólo es válida en el bloque { } en el cual se utilizó el compound literal.

a los campos no inicializados se les asigna ceros

16

Structures get copied, arrays get aliased

Aliasing: <programming> Two names (identifiers), usually of local or global variables, that refer to the same resource (memory location) are said to be aliased. Although names introduced in programming languages are typically mapped to different memory locations, aliasing can be introduced by the use of address arithmetic and pointers or language-specific features, like C/C++ references.

d1.x and d2.x are aliased.

17

El tamaño de una estructura

Es igual o mayor al tamaño de la suma de sus miembros; esto puede ser debido a que el computador agrega bytes de más a la estructura (padding) para acelerar el acceso del computador a la memoria. Varía con respecto al computador y al sistema operativo.

En el gcc se puede desactivar el padding con opción del compilador -fpack-struct Tenga en cuenta que esto disminuye la velocidad de acceso a la memoria

18

Padding, alignment, packing

Hecho en GNU/Linux de 32 bits

19

Padding

Padding hace un alineamiento de los miembros de la estructura de modo que las direcciones de memoria se alineen a 4 bytes o a 8 bytes, dependiendo si se tiene un sistema operativo de 32 o de 64 bits. Observe que las direcciones de memoria asignadas son divisibles entre 4 u 8 dependiendo del sistema operativo: ej: 0x80496ac == 134518444, el cual es un número divisible entre cuatro (ejecutado en GNU/Linux de 32 bits).

20

21

PackingEmpaqueta todo sin dejar espacios. El packing se debe hacer en los siguientes casos:

1) Cuando se debe sacrificar la velocidad del código a cambio de utilizar mejor la memoria RAM, en el caso que la memoria esté escasa.

2) Cuando se estén grabando estructuras a un archivo. En este caso el PADDING se debe desactivar y utilizar PACKING ya que si el archivo se lee en un computador con un sistema operativo diferente al sistema operativo que escribió el archivo podrían haber errores en la lectura de la estructura.

22

23

Offset de un elemento: offsetof()

offsetof(tipo,miembro)Este macro, definido en stddef.h, retorna el desplazamiento (“offset”) en bytes del elemento miembro de una struct, o union tipo, contado a partir del principio de la estructura.

24

Los operadores == y != no funcionan con estructuras. Si se quieren comparar dos estructuras, la comparación debe hacerse miembro a miembro.

Comparación de estructuras

25

No compare estructuras con memcmp()

Algunos programadores incorrectamente comparan estructuras utilizando:memcmp(&struct1, &struct2, sizeof(struct1));

Esto es incorrecto, ya que no se está teniendo encuenta que el padding entre los campos de las estructuras tiene un valor indeterminado. De otro, lado, en el caso que existan estructuras sin el padding, habrían problemas comparando punteros, doubles, floats, valores NAN, etc.

Por esta razón es preferible crear una función que compare dos estructuras miembro a miembro.

26

Como hacer una función que devuelva más de dos variables?

1. Pasando punteros

27

Como hacer una función que devuelva más de dos variables?

2. Retornando una estructura que contiene los valores deseados:

28

Como hacer una función que devuelva más de dos variables?

3. Utilizar un híbrido: pasar un puntero a una estructura, que posteriormente es llenada:

void

29

Arrays de estructuras

struct punto{ int x, y;};struct punto p[3];

Los elementos se pueden inicializar así:struct punto p[3] = { {2, 3}, {4, 5}, {6, 7} };

Para acceder a los elementos se hace lo siguiente:struct punto p[3];p[0].x = 2;p[0].y = 3;

30

Funciones que retornan vectoresSi se utiliza esta técnica se debe tener en cuenta que “vector” se está creando en la memoria de pila y el tamaño de esta es limitada.

31

Uniones (union)

● Se utilizan para guardar varias variables de diferentes tipos en el mismo espacio de memoria, por lo tanto si se asigna un valor a una variable, se sobreescribe el valor en las otras.

● Su tamaño es igual al tamaño de su elemento más grande: sizeof(mi_union) = sizeof(double)

● El compilador no verifica si los datos se están leyendo de la forma correcta.

32

Declaración de variables tipo union

33

Inicialización de uniones

Se puede inicializar la primera variable de la unión cuando se declara:

En este ejemplo el primer elemento (u1.c) se inicializa a 'm', pero union.x se deja "quieto".

También se puede inicializar cualquier otro miembro de la unión:

34

Accediendo a los miembros de una unión

Se hace utilizando el operador punto "."

Aquí u1.x sobreescribe u1.c

35

En este caso la unión nos permite crear un truco que permite devolver cualquier tipo de dato

unión anónima

36

Ejemplo uniones para entender la representación interna de un

número float

Ver un buen ejemplo de uniones en:http://tipsparaisc.blogspot.com/2012/12/representacion-interna-de-un-flotante.html

37

Arrays de unionesunion u{ int i; float f;};union u x[3];

Los tres primeros miembros de x se pueden inicializar como:

union u x[3] = { {3}, {4}, {5} };

(los brackets internos son opcionales)

Los elementos se acceden así:x[0].i = 2;

38

Campos de bits

Son estructuras cuyos miembros son paquetes de bits. Se utilizan para representar enteros de tamaño conocido. Se utilizan especialmente para "comprimir datos", o para representar series de bits en paquetes llamados "banderas" (flags). Se pueden crear utilizando unsigned int, signed int o _Bool.

39

40

Falta explicar estos comandos definidos en el C11

_Alignas_Alignof_Atomic_Generic_Noreturn

_Static_assert_Thread_local

Material basado en:

http://www.slideshare.net/amraldo/introduction-to-c-programming-7898353

http://www.slideshare.net/petdance/just-enough-c-for-open-source-programmers

http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html

Wikipedia