La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de 2009. Estructuras de datos. 1. Estructuras. 2. Campos de bits.

Presentaciones similares


Presentación del tema: "Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de 2009. Estructuras de datos. 1. Estructuras. 2. Campos de bits."— Transcripción de la presentación:

1 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Estructuras de datos. 1. Estructuras. 2. Campos de bits. 3. Uniones. 4. Tipos definidos por el usuario: typedef.

2 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Estructuras de datos. 1.Estructuras. Una estructura en C es una colección de variables no necesariamente del mismo tipo que se referencian por un nombre común. Esto permite crear una cierta organización de los datos dentro de un programa, colocando en estructuras los datos relacionados entre sí. Por ejemplo, los datos de un cliente, como pueden ser código, nombre, dirección, teléfono, etc., se colocarán en una única estructura, aunque sean datos de distintos tipos. Las distintas variables que forman parte de una estructura se denominan elementos o campos de la estructura.

3 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Definición y declaración de estructuras. Para usar estructuras en un programa, primero debe definirse el tipo de estructura, es decir una especie de plantilla donde se indica qué elementos o campos van a formar la estructura y de qué tipo es cada uno. Una estructura en C se define de la siguiente forma: struct nombre_estructura { tipo nombre_elemento_1; tipo nombre_elemento_2; }; En esta definición, los tipos pueden ser cualquier tipo válido en C, incluyendo arrays, punteros, otras estructuras, etc. Los elementos de la estructura no pueden ser inicializados en la definición del tipo de estructura. Ej:struct tipo_socio { long dni; char nombre[23]; char direccion[40]; };

4 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Definir una estructura no implica declarar ninguna variable, sino que se trata de una definición de un nuevo tipo de datos. En ese ejemplo, struct tipo_socio es un nuevo tipo, por lo que posteriormente podrán declararse variables de ese tipo, las cuales serán estructuras con los campos indicados. Para que un tipo de estructura definido en un programa esté disponible en todas las funciones, la definición de la estructura debe realizarse de modo global. Una vez definido el tipo de estructura, se podrán declarar variables de ese tipo, utilizando la siguiente sintaxis: struct nombre_estructura nombre_variable; En esa declaración, struct nombre_estructura es el tipo y nombre_variable es la variable creada de ese tipo, es decir que esa variable será una estructura, por lo que tendrá varios campos. Ej. struct tipo_socio socio;

5 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de O bien podemos declarar: struct tipo_socio { long dni; char nombre[23]; char direccion[40]; } socio1, socio2 ; En este ejemplo, al definir el tipo de estructura tipo_socio se declaran dos variables, socio1 y socio2, de ese tipo. Los campos de una variable de tipo estructura son almacenados secuencialmente en memoria, en el mismo orden en el que han sido definidos. Para referenciar o acceder a los elementos o campos de una variable de tipo estructura se usa el operador punto, de la forma siguiente: nombre_variable.nombre_elemento

6 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Por ejemplo, con la estructura definida previamente podremos escribir: socio.dni = ; //Variable de tipo long. strcpy(socio.nombre, Francisco García"); scanf(%s, socio.direccion); //Es cadena. scanf(%ld, &socio.dni); //Es numérico, lleva & Como estamos viendo, un elemento de una estructura puede ser un array, como nombre o dirección del caso anterior. Para referenciar o acceder a una sola componente del array se hará como en cualquier array, usando los corchetes. Una variable estructura puede asignarse completamente, con el operador =, a otra del mismo tipo, realizándose la asignación automáticamente para cada uno de los elementos, por lo que no es necesario ir asignando campo a campo. Esta asignación global sólo funciona si ambas estructuras son del mismo tipo. Ej. socio2 = socio1;

7 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Arreglos de estructuras. Cuando se declara un arreglo cuyo tipo es un tipo de estructura, se está declarando un arreglo de estructuras, por tanto cada componente del arreglo será una estructura. Todas las componentes del arreglo tendrán los mismos campos, definidos en el tipo de estructura. Esta es una construcción muy utilizada. struct nombre_estructura nombre_array[tamaño]; En esa declaración tamaño será el número de componentes del arreglo. Ej. struct tipo_socio socios[100]; El arreglo socios se crea con 100 componentes, cada una de las cuales es del tipo de estructura struct tipo_socio. Podría representarse en forma de tabla, con tantas filas como componentes tiene el array y tantas columnas como elementos tiene la estructura.

8 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de dninombredireccion socios[0] JOSE PEREZAVDA.ANCHA, 3 socios[1] JUAN HERNANDEZC.MAYOR, socios[99] PEDRO GARCIAAVDA.CENTRAL, 2 Para acceder a una celda de la tabla debe indicarse la fila y la columna. La fila viene dada por el nombre del arreglo más el número de la componente entre corchetes. La columna viene dada por el operador punto y el nombre del campo o elemento de la estructura. Ej. struct medidas { int ancho; int alto; int fondo;}; struct medidas muebles[50]; //para guardar las medidas de 50 muebles.

9 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de …………… muebles[2].ancho = 3; muebles[5].alto = muebles[2].ancho; scanf(%2d, &muebles[10].fondo); muebles[31] = muebles[30]; //Guarda una fila completa en otra, ………………. es decir una estructura, la 30, en otra, la 31. Arrays y estructuras dentro de estructuras. Los elementos de una estructura pueden ser simples (int, float, etc.) o bien compuestos, como un array, otra estructura o incluso un array de estrucutras. Para referenciar un dato concreto debe aplicarse el orden correcto de operadores punto para el elemento de la estructura y corchetes para la componente del array. Ej. Array dentro de una estructura: struct tipo_alumno { long dni; char nombre[20]; float notas[11]; } alumno; for (i = 0; i < 11; i++) alumno.notas[i] = -1; //Inicialización a -1.

10 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Ej. Estructura dentro de una estructura: struct tipo_expediente { int codigo; struct t_alumno alumno; } expendiente; scanf(%s, expediente.alumno.nombre); expediente.alumno.notas[10] = 8; scanf(%ld,&expediente.alumno.dni); //Necesita & Ej. Array de estructuras en las que un campo es otra estructura: struct tipo_expediente expediente[100]; //Tipo definido en el ejemplo anterior. scanf(%s, expediente[i].alumno.nombre); expediente[8].alumno.notas[10] = 8; scanf(%ld,&expediente[3].alumno.dni);

11 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Punteros a estructuras. Un puntero a una estructura se declara de igual manera que con otro tipo de variables, con el operador *. struct nombre_estructura *nombre_puntero; La dirección de una estructura se obtiene con el operador &, como con otros tipos de variables. Ej.struct tipo_reunion { int hora; char motivo[20]; } reunion; struct tipo_reunion *pst; pst = &reunion; //pst apunta a la estructura. En el acceso a la estructura a través de su puntero sí existe una diferencia con respecto al resto de tipos, ya que no se emplea el asterisco. Para acceder a cada campo o elemento de la estructura a través del puntero, se usa el operador -> Como sabemos, el operador punto se empleará cuando se accede a un elemento a través del nombre de la estructura. Debe tenerse en cuenta que el operador -> no nos da la dirección de un elemento de la estructura, no es un puntero, sino que nos da el contenido del elemento.

12 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Ej. pst->hora = 17; //Esa asignación es equivalente a: reunion.hora = 17; printf(Hora de la reunión: %d, p->hora); scanf(%d, &pst->hora); //Debe usarse & En ese ejemplo, aunque se use el puntero y el operador ->, debe usarse & en el scanf, ya que -> nos da el dato, no su dirección de memoria.

13 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Estructuras como parámetros de funciones. El paso de un elemento de una estructura como parámetro de una función es igual que pasar una variable del mismo tipo que ese elemento, que puede ser int, long, float, un array, etc. Ese paso de parámetro puede ser, como hemos visto, por valor o por referencia. Ej.struct tipo_empleado { long dni; float salario; char nombre[20]; } empleado; func1(empleado.dni); //Paso por valor de variable long. func2(&empleado.salario); //Paso por referencia de variable float. //Las funciones estarán declaradas como sigue: void func1(long x); //El parámetro es variable long. void func2(float *y); //El parámetro es puntero a variable float.

14 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Una estructura completa, con todos sus elementos, también puede ser pasada como parámetro de una función, tanto por valor como por referencia. Sin embargo, el paso por valor puede degradar el tiempo de ejecución del programa, sobre todo si la estructura es grande. Ello es debido a que cuando se usa el paso por valor, se crea una copia de la estructura original y la función trabaja con esa copia, por tanto se consume bastante tiempo en hacer esa copia y se consume memoria donde guardar la copia. Por ello, el paso de una estructura completa como parámetro de una función suele hacerse por referencia, ya que en este caso sólo se crea un puntero a la estructura y a través de ese puntero se accede a la estructura original, es decir que no existe una copia, de este modo la ejecución es más rápida y se ahorra memoria. Por otro lado, el paso por referencia permite que la función pueda modificar la estructura original, por lo que debe prestarse especial atención a las modificaciones no deseadas. Ej. #include struct datos { long salario; char nombre[20]; };

15 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de void func1( struct datos ); //El parámetro es de tipo estructura (por valor). void func2( struct datos *);//El parámetro es puntero a estructura (por refer.). void main(void) { struct datos personal; personal.salario = ; strcpy(personal.nombre, "Juan Hdez." ); func1(personal); //Se pasa la estructura completa. func2(&personal);//Se pasa un puntero a estructura. } void func1( struct datos perso ) { printf ("El salario es %ld \n", perso.salario ); printf ("El nombre es %s \n", perso.nombre ); } void func2( struct datos *p ) { scanf(%ld, &p->salario); scanf(%s, p->nombre); //Modifica la estructura original: personal, ya que p apunta a personal. }

16 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Estructuras y asignación dinámica de memoria. La reserva de memoria dinámica puede aplicarse a las estructuras, creándose por tanto las estructuras en tiempo de ejecución, a medida que se van necesitando. Se utiliza la misma sintaxis que para otro tipo de variables. La función malloc() devuelve un puntero al cual hay que especificarle el tipo. Ej. Reserva dinámica para una estructura. struct StEmp { long dni; char nombre[20]; float sueldo; }; struct StEmp *pst; pst=(struct StEmp *)malloc(sizeof(struct StEmp)); //Reserva memoria para una estructura de tipo StEmp. scanf(%ld, &pst->dni); //Usa operador flecha ->.

17 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de También podrá crearse un array de estructuras de forma dinámica, multiplicando la función sizeof() por el tamaño que queremos darle al array, dentro de la función malloc(). Ej. Reserva dinámica para un array de 10 estructuras. struct StEmp *pst; pst=(struct StEmp *)malloc(10*sizeof(struct StEmp)); pst+0 dninombresueldo pst pst scanf(%s, (pst+i)->nombre); //No lleva &. scanf(%f, &(pst+i)->sueldo); //Sí lleva &. //Accede al nombre y sueldo de la fila i del array

18 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Campos de bits. El lenguaje C permite, al contrario que la mayoría de los lenguajes de programación, el acceso a un bit individual dentro de un byte. Esta característica resulta muy práctica en algunas situaciones por los siguientes motivos: Ahorro de memoria: de los tipos de datos vistos hasta ahora, el que ocupa menos memoria es el tipo char, que ocupa 1 byte (8 bits). A veces con menos de 8 bits es suficiente para almacenar determinadas variables. Por ejemplo, si se desea almacenar en una variable el dato de ser mayor de edad o no, con 1 bit sería suficiente (0=no es mayor de edad; 1=sí es mayor de edad). O por ejemplo si se desea guardar en una variable el número del mes (de 1 a 12), con 4 bits es suficiente, ya que con 4 bits se pueden codificar 2 4 =16 valores, y sólo se necesitan 12. Esto puede hacerse usando campos de bits. Comunicación con ciertos periféricos: a veces la comunicación entre algunos periféricos y el ordenador se realiza a través de bits concretos dentro de un byte, por tanto debe accederse a esos bits independientes para poder realizar dicha comunicación. Esto también puede hacerse usando campos de bits.

19 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Para definir campos de bits en C debe usarse el tipo estructura. Un campo de bits siempre será un elemento dentro de una estructura. La definición general es: struct nombre_estructura { tipo campo_bit_1 : nºbits; tipo campo_bit_2 : nºbits;... } lista_de_variables; El tipo sólo puede ser int, para almacenar valores positivos y negativos, o unsigned para almacenar sólo valores positivos. El nºbits es el número de bits que ocupa cada campo de bit. La lista de variables puede declararse en un punto del programa diferente a donde se ha definido la estrucutra, de la forma: struct nombre_estructura lista_de_variables;

20 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Ej.struct tipo_alumno { unsigned m_edad : 1; //campo de 1 bit. unsigned nota : 4; //campo de 4 bits. unsigned curso : 2; //campo de 2 bits. }; struct tipo_alumno alumno; La variable alumno, que es una estructura del tipo tipo_alumno, que contiene 3 variables que son campos de bits, y ocupan solamente 7 bits en total. Realmente siempre se ocupan en memoria un número entero de bytes, el número necesario para que quepan todos campos de la estructura. Por tanto la estructura alumno ocupará 1 byte, ya que en 1 byte (8 bits) caben 7 bits. Si la estructura alumno anterior no hubiera empleado campos de bits, sino campos normales de tipo unsigned int, ocuparían 2 bytes cada campo, sumando un total de 6 bytes, en lugar de 1 byte que ocupa definiendo campos de bits. El campo m_edad puede guardar 0 o 1, por lo que con 1 bit es suficiente. El campo nota puede valer de 0 a 10 (11 valores distintos), por lo que con 4 bits es suficiente (2 4 =16), mientras que con 3 bits se hubiera quedado corto (2 3 =8). El campo curso puede guardar 1, 2 o 3, por lo que con 2 bits es suficiente (2 2 =4 valores, de 0 a 3).

21 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Una estructura que contenga campos de bits puede referenciarse mediante punteros, como cualquier otro tipo de estructura, así se puede acceder a un campo de bits a través del puntero que apunta a la estructura. Ej. Con la estructura alumno definida previamente: struct tipo_alumno *pst; pst = &alumno; //pst apunta a estructura alumno. pst -> nota = 7; //En el campo de bits nota guarda el valor 7. alumno.nota = 7; //También guarda un 7 en nota. Sin embargo, no se puede tomar la dirección de un campo de bits, ya que sería acceder a la dirección concreta de un bit dentro de un byte, lo cual no se puede. Esto implica que no se puede hacer un scanf() directamente sobre un campo de bits, por lo que el scanf() se hará sobre una variable auxiliar, de tipo int o unsigned int, cuyo valor se guardará después en el campo de bits. Ej. Con la estructura alumno definida previamente: unsigned *ptr; //puntero a variable unsigned. ptr = &(alumno.nota); //ERROR!. No está permitido, nota es campo de bits.

22 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Uniones. Una unión es una posición de memoria compartida por dos o más variables, en general, de distintos tipos. La definición de una unión es similar a la de una estructura, es decir primero se define el tipo de unión y posteriormente se declaran variables union de ese tipo, ya sea a continuación de la definición o en un punto diferente. union tipo_union { //define el tipo de unión. tipo elemento_1; tipo elemento_2;... } vari_union; //Declara variable vari_union. union tipo_union v_union; //Declara variable v_union. Los elementos de una unión (elemento_1, elemento_2, etc.) comparten las mismas posiciones de memoria. Una variable de tipo unión ocupará el número de bytes que ocupe el elemento de mayor tamaño. Si un elemento es int (2 bytes), otro es long (4 bytes) y el otro es char (1 byte), la variable de tipo unión ocupará 4 bytes.

23 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Ej. union ejemplo { int valor; //ocupa 2 bytes. char letra; //ocupa 1 byte. } ej1, ej2; //variables ej1 y ej2 de tipo union. union ejemplo ej3; //variable ej3 de tipo unión. En este ejemplo los elementos valor y letra comparten la misma ubicación en memoria. En cualquier momento el dato guardado en las uniones ej1 o ej2 o ej3 se puede usar como int o como char, dependiendo de si se referencia con el identificador valor o con letra. Como es lógico, el compilador reservará memoria para el tipo de elemento que mayor tamaño ocupe; en ese ejemplo, char ocupa 1 byte e int ocupa 2, por lo que las uniones ej1, ej2 y ej3 ocupan 2 bytes cada una. Para acceder a los elementos de una unión se usa el operador punto: Ej.ej1.valor = 3000; ej2.letra = 'A'; Si se define un puntero a una unión, se usará el operador flecha (->) para acceder a los elementos de la unión, como en las estructuras: Ej.union ejemplo *ptr; ptr->valor = 1500; //También se modifica el elemento letra.

24 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Tipos Definidos por el Usuario: typedef. El C tiene una utilidad para dar nuevos nombres a los tipos de datos ya existentes, pero no crea ningún tipo de datos nuevo, simplemente renombra. Esos nombres son elegidos por el programador. Esto será utilizado para hacer más legible un programa. La forma de definirse es: typedef tipo_existente nuevo_nombre_tipo; Ej. typedef int entero; //Nuevo nombre para el tipo int. typedef char *cadena; //Tipo cadena será puntero a char typedef char linea[80]; //Tipo linea: array de 80 char Ahora se podrán declarar variables con esos nuevos nombres para los tipos. Ej. entero x,y,z; // Tres variables enteras: int. cadena cad; // cad es variable puntero a char. linea lin; // lin es variable de 80 caracteres.

25 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Ejemplo con Estructuras: Declaraciones de tipos para manejar listas en C: typedef struct _nodo { int dato; struct _nodo *siguiente; } tipoNodo; typedef tipoNodo *pNodo; tipoNodo es el tipo para declarar nodos. pNodo es el tipo para declarar punteros a un nodo.

26 Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de Terminamos por hoy. La semana que viene empezamos con manejo de archivos.


Descargar ppt "Programación, Algoritmos y Estructuras de Datos. Facultad de Ingeniería – UNLP. Junio de 2009. Estructuras de datos. 1. Estructuras. 2. Campos de bits."

Presentaciones similares


Anuncios Google