Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Unidad 6 Estructuras Estaticas
Unidad 6 Estructuras Estaticas
es
(3)
(6.7) uniones __________________________________________________________________________ 36 (6.8) campos de bits ___________________________________________________________________ 37 (6.9) enumeraciones ___________________________________________________________________ 37
(5)
fundamentos de programacin
(Unidad 6) estructuras estticas
(6.2) introduccin
En programacin se llaman estructuras estticas a datos compuestos de datos simples (enteros, reales, caracteres,...) que se manejan como si fueran un nico dato y que ocupan un espacio concreto en memoria. Las estructuras estticas son:
(6.3) arrays
(6.3.1) introduccin
Imaginemos que deseamos leer las notas de una clase de 25 alumnos. Desearemos por tanto almacenarlas y para ello con lo que conocemos hasta ahora no habr ms remedio que declarar 25 variables. Eso es tremendamente pesado de programar. Manejar esas notas significara estar continuamente manejando 25 variables. Por ello en C (como en casi todos los lenguajes) se pueden agrupar una serie de variables del mismo tipo en una misma estructura. Esa estructura permite referirnos a todos los elementos, pero tambin nos permite acceder individualmente a cada elemento. Los arrays son una coleccin de datos del mismo tipo al que se le pone un nombre (por ejemplo nota). Para acceder a un dato individual de la coleccin hay que utilizar su posicin. La posicin es un nmero entero, normalmente se le llama ndice (por ejemplo nota[4] es el nombre que recibe el cuarto elemento de la sucesin de notas). Hay que tener en cuenta que en los arrays el primer elemento tiene como ndice el nmero cero. El segundo el uno y as sucesivamente; es decir nota[4] en realidad es el quinto elemento del array.
(6)
(7)
fundamentos de programacin
(Unidad 6) estructuras estticas
Tanto para escribir como para leer no se puede utilizar el nombre completo del array. Es decir: scanf(%d,nota); no lee todas las notas (de hecho slo lee la primera), no tiene sentido ese uso. Tampoco se puede: printf(%d,nota);
(8)
esa instruccin simplemente mostrar la direccin de memoria en la que est almacenado el array. Otro ejemplo (array que almacena y muestra los 20 primeros factoriales); double factorial[21]; int i; factorial[0]=1; for(i=1;i<21;i++){ factorial[i]=i*factorial[i-1]; } /*Mostrar el resultado*/ for(i=0;i<21;i++){ printf("El factorial de %d es .0lf\n",i,factorial[i]); } iniciar arrays en la declaracin C posee otra manera de asignar valores iniciales al array. Consiste en poner los valores del array entre llaves en la declaracin del mismo. Ejemplo: int nota[10]={3,5,6,7,3,2,1,7,4,5}; nota[0] valdr 3, nota[1] valdr 5, nota[2] valdr 6 y as sucesivamente. Las llaves slo se pueden utilizar en la declaracin. Si hay menos elementos en las llaves de los que posee el array entonces se rellenan los elementos que faltan con ceros, ejemplo: int nota[10]={3,5}; int i=0; for(i=0;i<10;i++) printf("%3d",nota[i]); El resultado es: 5 0 0 0 0 0 0 0 0
es decir, nota[0] valdr 3, nota[1] valdr 5, y el resto se rellena con ceros. En el caso de que haya ms elementos en las llaves de los que declaramos en el array, por ejemplo: int a[2]={3,5,4,3,7}; Esa instruccin produce un error. Otra posibilidad es declarar el array sin indicar el tamao y asignarle directamente valores. El tamao del array se adaptar al tamao de los valores: (9)
fundamentos de programacin
(Unidad 6) estructuras estticas
int a[]={3,4,5,2,3,4,1}; /* a es un array int[7] */ desbordamiento de ndice En C hay que tener un cuidado especial con los ndices, por ejemplo este cdigo es errneo: int a[4]; a[4]=13; No hay elemento a[4] (el ltimo es a[3]), por lo que ese cdigo no tiene sentido. Sin embargo en C no se nos advierte del fallo, de hecho el uso de a[4] permite almacenar el nmero 13 en la posicin del que sera el quinto elemento del array. Por lo tanto lo que ocurre es que el programa escribe fuera del array (en lo que puede ser el rea ocupada por otra variable), lo que provocara que el programa no funcione correctamente y acte de manera imprevisible. Hay que tener mucho cuidado con este tipo de errores, conocidos como errores de desbordamiento de ndice de array. Ya que hace que manipulemos la memoria sin control alguno. Los programas fallan en su ejecucin, pero ser muy difcil detectar por qu. uso de la directiva #define Una buena prctica de programacin consiste en utilizar constantes en lugar de nmeros para indicar el tamao del array. En el ejemplo anterior de las notas, ocurre que en lugar de 21 notas, ahora queremos 30, tendremos que cambiar todos los 21 por 30 a lo largo del cdigo. En su lugar es ms conveniente: #define TAMANIO 20 int nota[TAMANIO]; /* Contador para recorrer el array */ int i; for(i=0;i<TAMANIO;i++) { printf(Escriba la nota %d:,i); scanf(%d,¬a[i]); } La directiva #define permite definir macros. El compilador sustituir el nombre TAMANIO por 20 antes de compilar. Si resulta que ahora el nmero de notas es otra (por ejemplo 30), basta cambiar slo la lnea del define y no el resto.
En el tema anterior (dedicado a las funciones), ya se coment la que significaba pasar como valor o pasar por referencia una variable. Cuando se pasa por valor, se toma una copia del valor del parmetro; por referencia se toma la direccin del dato. La funcin scanf requiere que el segundo argumento se pase por referencia para almacenar los valores del teclado en una direccin concreta. Cuando las variables son simples, la direccin de la variable se toma mediante el operador &. Por ejemplo, si a es una variable entera, &a devuelve la direccin de dicha variable. En el caso de los arrays hay que tener en cuenta que la direccin en la que comienza el array es la direccin de su primer elemento. Es decir si nota es un array, los valores de ese array se empieza a almacenar en ¬a[0], es decir en la direccin de la primera nota; consecutivamente se irn almacenando el resto. Lo importante es que la variable que hace referencia a todo el array (por ejemplo nota) en realidad apunta al primer elemento del array (ms adelante diremos que es un puntero). Con lo dicho anteriormente hemos de tener claro que nota y ¬a[0] se refieren a la direccin de memoria en la que se almacena el primer valor del array.: int nota[8]={4,6,7,6,8,9,8,4}; printf(%d\n,¬a[0]); /* Escribe una direccin de memoria */ printf(%d\n,nota); /* Escribe la misma direccin */ printf(%d\n,¬a); /* De nuevo escribe la misma direccin */ En el ejemplo anterior, la tercera lnea que escribe ¬a, denota que ¬a y nota es la misma cosa. De esta forma hay que tener en cuenta que cuando se utiliza un array como parmetro de una funcin, lo que sta recibe es una referencia al primer elemento. Por ejemplo, supongamos que queremos calcular la media aritmtica de un array de enteros. Crearemos entonces la funcin media que recibe dos parmetros: un array de enteros y el tamao de dicho array. El tamao es necesario ya que desde la funcin no sabremos cul ser dicho tamao. El cdigo ser: double media(int numero[], int tamanio){ double res; int i; for(i=0;i<tamanio;i++){ res+=numero[i]; /* Se acumula en res la suma total del array */ } return res/tamanio; /* res/tamanio es la media */ } (11)
fundamentos de programacin
(Unidad 6) estructuras estticas
Hay que tener en cuenta que si en una funcin se cambia el valor de un elemento del array, ese cambio de valor afecta al array original. Esto se debe al hecho de que el array se pase por referencia y no por valor. Si una funcin utiliza un parmetro de tipo int y se cambia su valor en la funcin, eso no significa que se cambie el valor original. Es decir en el ejemplo: #include <stdio.h> void prueba(int x); int main(){ int a=12; prueba(a); /*Se llama a la funcin prueba con el valor a */ printf(%d,a); /* escribir el valor 12 */ } void prueba(int x){ x=3; } Al llamar a la funcin prueba, el parmetro x toma una copa de a. A esa copia le pone el valor 3. Cuando el programa regresa de la funcin, el valor de a no ha cambiado. En este otro caso: #include <stdio.h> void prueba(int[] x); int main(){ int a[4]; a[0]=12; prueba(a); /*Se llama a la funcin prueba con el valor a */ printf(%d,a[0]); /* escribir el valor 3 */ } void prueba(int[] x){ x[0]=3; } aqu el valor del elemento a[0] s que cambia por que en la funcin prueba, x no es una copa de a; x y a son la misma cosa, la direccin del mismo array. El modificador const permite restringir la escritura de un array cuando es utilizado como parmetro. Si se modifica el array ocurrir un error en la ejecucin.
(12)
(13)
fundamentos de programacin
(Unidad 6) estructuras estticas
bsqueda binaria Se basa en que el array que contiene los valores est ordenado. En ese caso la bsqueda anterior es excesivamente lenta. Este algoritmo consiste en comparar el valor que buscamos con el valor que est en el centro del array; si ese valor es menor que el que buscamos, ahora buscaremos en la mitad derecha; si es mayor buscaremos en la mitad derecha. Y as hasta que lo encontremos. Una variable (en el cdigo es la variable central) se encarga de controlar el centro del array que nos queda por examinar, las variables bajo y alto controlan los lmites (inferior y superior respectivamente) que nos quedan por examinar. En caso de que el valor no se encuentre, entonces los lmites bajo y alto se cruzan. Entonces el algoritmo devuelve -1 para indicar que el valor no se encontr. Esta bsqueda es rapidsima ya que elimina muchas comparaciones al ir quitando la mitad de lo que nos queda por examinar. Cdigo de bsqueda binaria: /* parmetros: vector: Array que contiene todos los valores tamanio: Tamao del array valor: valor a buscar */ int busquedaBinaria(int array[], int tamanio, int valor){ int central,bajo=0,alto=tamanio-1; int encontrado=0; while(encontrado==0 && bajo<=alto){ central=(bajo+alto)/2; if(valor== array[central]) return central; else if (valor< array[central]) /* Se busca en la mitad izquierda */ alto=central-1; else /* Se busca en la mitad derecha */ bajo=central + 1; }/* Fin del while */ if (encontrado) return central; return -1; /* No se encontr */ } (14)
ordenacin de arrays Se trata de una de las operaciones ms tpicas de la programacin. Un array contiene datos sin ordenar, y tenemos que ordenarle. mtodo por insercin directa Consiste en que el array est en todo momento ordenado y cada vez que se aade un elemento al array, ste se coloca en la posicin que corresponda. Para ello habr que desplazar elementos. Si el array es: 1 2 3 5 6 7
se han tenido que desplazar los valores 5,6 y 7 para hacer hueco al 4 en su sitio. Para un array de enteros la funcin que inserta un nuevo valor en dicho array sera: /* Parmetros de la funcin: array: Array que contiene los datos ya ordenados tamanio: Tamao actual del array, es el tamao de los datos ordenados. cero significa que an no se ha insertado ningn valor valor: El nuevo valor a insertar en el array */ void insercion(int array[], int tamanio, int valor){ /* valor es el valor que se inserta */ int i,pos=0; int enc=0; /* indica si hemos encontrado la posicion del elemento a insertar*/ if (tamanio==0) /*Si no hay datos aadimos este y salimos*/ array[0]=valor; else{ /* Hay datos */ /*Localizar la posicin en la que ir el nuevo valor*/ while(enc==0 && pos<tamanio ){ if(valor<array[pos]) enc=1; else pos++; }
(15)
fundamentos de programacin
(Unidad 6) estructuras estticas
/* Desplazar los elementos necesarios para hacer hueco al nuevo */ for(i=tamanio-1;i>=pos;i--) array[i+1]=array[i]; /*Se coloca el elemento en su posicin*/ if(pos<=tamanio) array[pos]=valor; }/*fin del else */ } mtodo burbuja Para ordenar un array cuando ya contiene valores y stos no estn ordenados, no sirve el mtodo anterior. Para resolver esa situacin, el algoritmo de ordenacin de la burbuja o de intercambio directo es uno de los ms populares. Consiste en recorrer el array n veces, donde n es el tamao del array. De modo que en cada recorrido vamos empujando hacia el principio del array los valores pequeos (si ordenamos en ascendente). Al final, el array est ordenado. La funcin que ordenara mediante el mtodo de la burbuja un array de enteros de forma ascendente. Cdigo: void burbuja(int array[], int tamanio){ int i,j; int aux; /* Auxiliar para realizar el intercambio */ for(i=0;i<tamanio;i++){ for(j=0;j<tamanio-1;j++){ if(array[j]>array[j+1]){ /* intercambia los elementos, swap*/ aux=array[j]; array[j]=array[j+1]; array[j+1]=aux; } } } }
(16)
mtodo de ordenacin rpida o quicksort Es uno de los mtodos ms rpidos de ordenacin. Se trata de un algoritmo recursivo que permite ordenar indicando primero que parte del array se quiere ordenar. Inicialmente se indica ordenar desde el primero al ltimo elemento del array., consiste en dividir lo que se desea ordenar en varios trozos que se van ordenando recursivamente. /* Parmetros de la funcin: a: Array que contiene los datos ya izda: Posicin inicial desde la que se ordena el array dcha: Posicin final hastala que se ordena el array */ void quicksort(int a[], int izda, int dcha) { /* Funcin auxiliar que sirve para intercambiar dos elementos dentro del array*/ void swap(int a[],int i,int j){ int aux; aux=a[i]; a[i]=a[j]; a[j]=aux; }
int i,j,v,aux; if(dcha > izda) { v = a[dcha]; i = izda-1; j = dcha; for(;;){ while(a[++i] < v && i < dcha); while(a[--j] > v && j > izda); if(i >= j) break; swap(a,i,j); } swap(a,i,dcha); quicksort(a,izda,i-1); quicksort(a,i+1,dcha);} } La llamada a esta funcin para ordenar un array es quicksort(0,tamanio), donde tamanio es el tamao del array menos uno. (17)
fundamentos de programacin
(Unidad 6) estructuras estticas
4 5 6
5 4 3
6 2 5
8 8 7
9 5 8
3 8 9
Si esos fueran los elementos de un array de dos dimensiones (por ejemplo el array a) el elemento resaltado (de verde) sera el a[3][1]. La declaracin de arrays de dos dimensiones se realiza as: int a[3][6]; a es un array de tres filas y seis columnas. Otra forma de declarar es inicializar los valores: int a[][]={{2,3,4},{4,5,2},{8,3,4},{3,5,4}}; En este caso a es un array de cuatro filas y tres columnas. Al igual que se utilizan arrays de dos dimensiones se pueden declarar arrays de ms dimensiones. Por ejemplo imaginemos que queremos almacenar las notas de 6 aulas que tienen cada una 20 alumnos y 6 asignaturas. Eso sera un array de una dimensin de 720 elementos, pero es ms claro el acceso si hay tres dimensiones: la primera para el aula, la segunda para el alumno y la tercera para la asignatura. En ese caso se declarara el array as: int a[6][20][6]; Y para colocar la nota en el aula cuarta al alumno cinco de la asignatura 3 (un ocho es la nota): a[3][4][2]=8; Cuando un array multidimensional se utiliza como parmetro de una funcin, entonces se debe especificar el tamao de todos los ndices excepto del primero. La razn est en que de otra forma no se pueden calcular los ndices correspondientes por parte de la funcin. Es decir: void funcion(int a[][]); Eso es incorrecto, en cuanto hiciramos uso de un acceso a a[2][3], por ejemplo, no habra manera de saber en qu posicin de memoria est ese valor ya que sin (18)
saber cuntas columnas forman parte del array, es imposible determinar esa posicin. Lo correcto es: void funcion(int a[][5]);
(6.4) punteros
(6.4.1) introduccin
Se trata de una de las herramientas ms importantes de C. Se trata de una variable cuyo contenido es la direccin de otra variable. Por ello se dice que la variable-puntero seala a la otra variable. A estas variables se las llama tambin apuntadores y pointers (aunque es mucho ms utilizado el nombre de puntero). Supongamos que tenemos una variable x a la que le hemos dado el valor 15; supongamos tambin que el valor de x se almacena en la direccin 160000 de memoria. Finalmente si p es un puntero cuyo valor es el nmero160000, entonces p seala a x.
(en la direccin 16000 de memoria)
(variable puntero)
15
160000
x
15
Desde ese momento podramos utilizar p para modificar x. Un puntero siempre sirve para acceder a otras variables. La utilidad de los punteros es diversa y se ir desglosando a lo largo de este apartado. Las ms importantes:
Pasar parmetros a funciones utilizado paso por referencia. Manejar de forma avanzada arrays Facilitar la escritura de cdigo complejo Manipular estructuras dinmicas de datos, mediante el uso de malloc y
free.
(19)
fundamentos de programacin
(Unidad 6) estructuras estticas
Ese mismo operador se utiliza para cambiar el valor de la variable a la que apunta el puntero. Ejemplo: int *ptrSuma, suma=18; ptrSuma=&suma; *ptrSuma=11; printf(%d,x); /* Escribe 11, ahora x vale 11*/ En el ejemplo, se ha utilizado ptrSuma para modificar el valor de la variable x.
fundamentos de programacin
(Unidad 6) estructuras estticas
y tiene el cubo de la variable x (83). Pero otra forma podra ser usando el cubo con paso por referencia. La funcin podra ser: void cubo(double *ptrX){ *ptrX=*ptrX * *ptrX * *ptrX; } A esta funcin se la pasa la direccin de un nmero double, direccin que ser recogida por un puntero. Dentro de la funcin se usa el puntero para modificar el contenido al que apunta y eso modificar la variable original. La llamada ala funcin podra ser: double y=8.0; cubo(&y); en esta llamada y pasa su direccin a la funcin cubo. De esta forma cubo tiene un puntero a y con el que modifica su contenido. Este es un buen ejemplo de variable pasada por referencia.
(22)
fundamentos de programacin
(Unidad 6) estructuras estticas
Desde ese momento se pueden utilizar los ndices del array o la aritmtica de punteros para sealar a determinadas posiciones del array. Es decir: es lo mismo A[3] que ptr+3. De esta forma tambin son equivalentes estas instrucciones: x=A[3]; x=*(ptr+3); Pero la analoga entre punteros y arrays es tal, que incluso se pueden utilizar ndices en el puntero: x=ptr[3]; Tambin sera vlido (con lo cual se observa ya la gran equivalencia entre arrays y punteros): x=*(A+3); Es decir, son absolutamente equivalentes los arrays y los punteros. Una de las grandes utilidades de esta capacidad es utilizar esta equivalencia para pasar punteros que sealan a arrays en las funciones (en ligar de utilizar realmente arrays). Aunque A se parece mucho a un puntero, se ha definido como array. Por ello, no se permite hacer: A++ Ya que eso dejara sin referencia al array. Las variables de array no se pueden modificar.
(24)
fundamentos de programacin
(Unidad 6) estructuras estticas
(26)
fundamentos de programacin
(Unidad 6) estructuras estticas
No obstante esta declaracin compiladores (otra vez en Dev cadenas, como se almacenan en Es mejor (si se van a modificar ejemplo:
tambin genera problemas en numerosos C++ por ejemplo) ya que al modificar esas la zona de constantes, tendramos problemas. los textos) declarar reservando memoria, por
char s[4][50]={"Ana","Pablo","Julin","Roberto"}; puts(s[2]); /* Escribe Julin */ La declaracin en este caso crea un array bidimensional de 4 x 50 caracteres. Eso se puede interpretar como cuatro arrays de caracteres de 50 caracteres como mximo cada uno. As los textos utilizados en el ejemplo se copian en el rea reservada por el array y s se podran modificar. Si deseamos un puntero sealando a la segunda cadena del array: char *p=s[2]; puts(p); /*Tambin escribe Julin */ Eso es vlido ya que s[2] es el tercer elemento del array s, es un array de 50 caracteres. Es decir, s[2] es la tercera cadena del array de cadenas s.
(28)
prototipo de la funcin int ispunct(int carcter) int isprint(int carcter) int isgraph(int carcter)
descripcin Devuelve verdadero si el carcter es de puntuacin Devuelve verdadero si el carcter no es de control Devuelve verdadero si el carcter no es de control y no es el espacio
funciones de conversin de cadenas La librera stdlib.h contiene varias funciones muy interesantes para procesar cadenas son:
prototipo de la funcin double atof(char *s) descripcin Convierte la cadena s a formato double. Si la cadena no contiene datos que permitan la conversin (por ejemplo si contiene texto), su comportamiento es impredecible. Convierte la cadena s a formato int. Si la cadena no contiene datos que permitan la conversin (por ejemplo si contiene texto), su comportamiento es impredecible. Convierte la cadena s a formato long. Si la cadena no contiene datos que permitan la conversin (por ejemplo si contiene texto), su comportamiento es impredecible.
funciones de manipulacin de cadenas La librera string.h proporciona las funciones ms interesantes para manipular cadenas:
prototipo de la funcin char * strcat(char *s1, char *s2) char * strcpy(char *s1, char *s2) int strcmp(char *s1, char *s2) descripcin Aade s2 al final de la cadena s1. Devuelve la propia s1 Copia s2 en s1. Devuelve la propia s1 Compara s1 con s2. Si s1 es mayor devuelve un valor positivo, si es menor un valor negativo y si son iguales devuelve 0. Busca la primera vez que aparece el carcter dentro de la cadena s1 si le encuentra devuelve un puntero al mismo, sino devuelve el valor NULL. Busca la ltima vez que aparece el carcter dentro de la cadena s1 si le encuentra devuelve un puntero al mismo, sino devuelve el valor NULL.
(29)
fundamentos de programacin
(Unidad 6) estructuras estticas
descripcin Busca la primera vez que aparece el texto s2 de la cadena s1. Si le encuentra devuelve un puntero al primer carcter de s2 dentro de s1, sino devuelve el valor NULL. Devuelve el tamao del texto s. Divide la cadena en tokens, es decir, partes
de la cadena delimitados por una determinada cadena. La primera llamada debe utilizar en el parmetro tokens el o los caracteres delimitadores. Por ejemplo en una llamada strtok(s,,) nos devolvera el texto de s que hay hasta llegar a la primera coma. En las siguientes llamadas se debe utilizar el valor NULL. As si la siguiente es strtok(NULL,,) devolver el trozo de texto desde la primera coma a la segunda. Y as sucesivamente. Si no hay ms tokens, devuelve NULL. Es una funcin potentsima. Ejemplo de uso de tokens: char x[100]="Esto, es, una, funcion delimitada, con tokens"; char *aux; aux=strtok(x,",");/*La primera llamada usa x*/ while(aux!=NULL){ cout<<aux<<endl; aux=strtok(NULL,","); /*Las siguientes usan NULL*/ } /* Sale: Esto es una funcion delimitada con tokens */
(30)
(6.6) estructuras
Son colecciones de variables de distinto tipo agrupadas bajo un mismo nombre. Son equivalentes a los registros de otros lenguajes. Representan fichas de datos referidas a la misma cosa.
(6.6.1) definicin
Se trata de un tipo de datos formado por medio de variables de otros tipos. Por ejemplo: struct persona{ char nombre[25]; char apellidos[50]; char dni[10]; int edad; }; Esa instruccin define un tipo de estructura, pero no declara variable alguna. Las variables de estructura se definen as: struct persona pepe; pepe es una variable de tipo persona. La definicin de la estructura se suele hacer en la zona global (antes del main) para que sea accesible a cualquier funcin del programa.
(6.6.2) typedef
Una forma mucho ms interesante de utilizar estructuras, consiste en declararlas como definicin de tipos. El ejemplo anterior podra utilizarse de esta forma: struct persona{ char nombre[25]; char apellidos[50]; char dni[10]; int edad; }; typedef struct persona Persona; Con esa instruccin acabamos de definir el tipo Persona (a los nombres de tipo se les suele poner la primera letra en maysculas). Ese tipo se puede utilizar igual que los propios de C. Es decir: Persona pepe; /* pepe es una variable de tipo Persona */ (31)
fundamentos de programacin
(Unidad 6) estructuras estticas
pepe es una variable de tipo Persona. Se puede hacer todo lo anterior de esta forma (definiendo la estructura y creando el tipo a la vez). Ejemplo: typedef struct{ char nombre[25]; char apellidos[50]; char dni[10]; int edad; }Persona; As se define directamente el tipo Persona. Otra vez podramos usar: Persona pepe; Es mucho ms aconsejable este mtodo que el anterior.
(32)
typedef struct{ char nombre[25]; char apellidos[50]; int edad; Direccion direccion; } Alumno; En la definicin del tipo de estructura Alumno se utiliza la variable de estructura direccion. Eso se podra hacer tambin como: typedef struct{ char nombre[25]; char apellidos[50]; int edad; struct{ char tipoVia; char nombre[50]; int numero; int piso; char puerta[10]; } direccion; } Alumno; Pero es menos recomendable, ya que en el primer modo, se pueden crear variables de tipo Direccion independientemente de la estructura Alumno. Si declaramos una variable de tipo Alumno como: Alumno pedro; El acceso por ejemplo al nmero de la direccin de pedro se hara: pedro.direccion.numero=7;
fundamentos de programacin
(Unidad 6) estructuras estticas
jaime=pepe; En el ejemplo, la variable jaime contendr los mismos valores que pepe. comparaciones Las variables de estructura, no se pueden comparar con los operadores ==, >=, .... En su lugar habr que comparar cada dato miembro. operador sizeof Este operador permite obtener el tamao en bytes de una estructura. Por ejemplo: printf("\n%d", sizeof pepe); En el ejemplo anterior se devuelven los bytes que ocupa en memoria la variable pepe.
(34)
Tras crear dicho tipo, podemos crear un array de Personas de esta forma: Persona amigos[15]; Para utilizar dicho array: Persona amigos[10]; amigos[0].nombre="Alfonso"; amigos[0].edad=25; amigos[1].nombre="Ana"; amigos[1].edad=31; puts(amigos[1].nombre); punteros a estructuras Ejemplo: Persona ana; Persona *ptr1=&ana; ptr1 es un puntero que seala a variables de tipo Persona. En este ejemplo, ese puntero seala a ana ya que toma su direccin. Para acceder a los valores a los que seala el puntero, no se utiliza la expresin *ptr1 a la que estbamos acostumbrados, sino que se utiliza el operador ->. De esta forma: strcpy(ptr1->nombre,"Ana"); strcpy(ptr1->apellidos,"Fernandez Castro"); ptr1->edad=19; printf("%s %s",ptr1->nombre,ptr1->apellidos); En el ejemplo la expresin ptr1->nombre, es equivalente a ana.nombre.
fundamentos de programacin
(Unidad 6) estructuras estticas
La funcin sera: void subirEdad1(Persona pers){ pers.edad++; } Pero en la llamada: subirEdad1(pedro); printf("%d",pedro.edad); La edad de pedro no cambia tras la llamada. La razn es que la estructura se ha pasado por valor. Con lo que el contenido se copia en la funcin a la variable pers, y esa es la variable que se modifica. No se ha cambiado la estructura original. La forma de pasar estructuras por referencia es utilizar punteros (al igual que en el caso de cualquier otra variable). As el formato de la funcin sera: void subirEdad2(Persona *ptrPers){ ptrPers->edad++; } Y la llamada se hara: subirEdad2(&pedro); printf("%d",pedro.edad); /* Sale 24, un ao ms */
(6.7) uniones
Es un tipo de dato muy parecido a las estructuras. En este caso los miembros comparten el mismo espacio de almacenamiento. El gasto en bytes de las uniones ser el correspondiente al miembro que gasta ms espacio. El caso tpico de unin sera: union numero{ int x; double y; }; Lo que ganamos es que podemos asignar a esa variable valores tanto enteros como de tipo double. Ejemplo: union numero1 valor = {10}; /*El 10 se almacena como entero*/ union numero2 valor = {1.03}; /*Se almacena como double*/ (36)
En el caso de asignar valores, se obra como si fuera una estructura: Color c1; c1.rojo=3; c1.verde=0; c1.azul=0; c1.transpar=5; Se utiliza para empaquetar bits que tienen un significado especial.
(6.9) enumeraciones
Las enumeraciones son otro tipo definido por el usuario que sirve para definir un conjunto entero de constantes de enumeracin. Las constantes de enumeracin son identificadores (que se suelen poner en maysculas) asociados a nmeros enteros. Gracias a las enumeraciones se pueden utilizar tipos de datos que aportan una mayor claridad en el cdigo.
(37)
fundamentos de programacin
(Unidad 6) estructuras estticas
Ejemplo: enum meses{ ENE, FEB, MAR, ABR, MAY, JUN, JUL, AGO, SEP, OCT, NOV, DIC }; Las constantes de enumeracin (de ENE a DIC) tomarn valores de 0 a 11. Si deseramos que tomarn valores de 1 a 12: enum meses{ ENE=1, FEB, MAR, ABR, MAY, JUN, JUL, AGO,SEP, OCT, NOV, DIC }; Para declarar una variable de tipo enum se hara: enum meses m1; Tambin se puede utilizar typedef, para definir un tipo propio. De hecho se suele utilizar ms: typedef enum { ENE=1, FEB, MAR, ABR, MAY, JUN, JUL, AGO,SEP, OCT, NOV, DIC }Meses; ... Meses m1; Despus se pueden utilizar las constantes definidas para asignar valores a la variable de enumeracin: m1=JUL; /* Es lo mismo que m1=7 */
(38)
Ejemplo completo de uso de enum: typedef enum{ ESO1, ESO2, ESO3, ESO4, FP1, FP2, BACH1, BACH2, PREU }Clases;
"Primero de ESO", "Segundo de ESO", Tercero de ESO", "Cuarto de ESO", "Formacin profesional 1", "Formacin profesional 2", "Bachiller 1", "Bachiller 2", "Preuniversitario"
}; int i; for(i=ESO1;i<=PREU;i++){ puts(nombreClases[i]); } } Ese bucle, muestra los nombres de todas las clases. Ese listado se poda hacer sin enumeraciones, pero el cdigo es as mucho ms claro.
(39)