Está en la página 1de 39

Para ver una copia completa de la licencia, acudir a la direccin http://creativecommons.org/licenses/by-nc-sa/2.5/es/legalcode.

es

(3)

(unidad 6) Estructuras estticas


(6.1) esquema de la unidad
(6.1) esquema de la unidad _____________________________________________________________ 5 (6.2) introduccin ______________________________________________________________________ 6 (6.3) arrays ____________________________________________________________________________ 6 (6.3.1) introduccin 6 (6.3.2) declaracin de arrays 7 (6.3.3) utilizacin de arrays 8 (6.3.4) pasar un array como parmetro de una funcin 10 (6.3.5) algoritmos de bsqueda y ordenacin en arrays 13 (6.3.6) arrays multidimensionales 18 (6.4) punteros _________________________________________________________________________ 19 (6.4.1) introduccin 19 (6.4.2) declaracin de punteros 20 (6.4.3) operaciones con punteros 20 (6.4.4) punteros como parmetros de funciones 21 (6.4.5) funciones que devuelven punteros 22 (6.4.6) aritmtica de punteros 23 (6.4.7) punteros y arrays 23 (6.5) cadenas de caracteres ____________________________________________________________ 24 (6.5.1) introduccin 24 (6.5.2) declarar cadenas 25 (6.5.3) leer y escribir cadenas 26 (6.5.4) comparar cadenas 26 (6.5.5) funciones y cadenas 27 (6.5.6) arrays de cadenas 27 (6.5.7) funciones de uso con cadenas 28 (6.6) estructuras_______________________________________________________________________ (6.6.1) definicin (6.6.2) typedef (6.6.3) acceso a los miembros de una estructura (6.6.4) estructuras dentro de estructuras (6.6.5) operaciones con estructuras (6.6.6) arrays y punteros a estructuras (6.6.7) estructuras y funciones 31 31 31 32 32 33 34 35

(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:

Arrays. Tambin llamadas listas estticas, matrices y arreglos (aunque quiz


lo ms apropiado es no traducir la palabra array). Son una coleccin de datos del mismo tipo.

Cadenas. Tambin llamadas strings. Se trata de un conjunto de caracteres


que es tratado como un texto completo.

Punteros. Permiten definir variables que contienen posiciones de memoria;


son variables que se utilizan para apuntar a otras variables

Estructuras. Llamadas tambin registros. Son datos compuestos de datos


de distinto tipo. Una estructura podra estar compuesta de un entero, un carcter y un array por ejemplo.

(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)

1er curso de administracin de sistemas informticos autor: Jorge Snchez www.jorgesanchez.net

Ilustracin 1, Ejemplo de array

(6.3.2) declaracin de arrays


Un array ocupa un determinado espacio fijo en memoria. Para que el ordenador asigne la cantidad exacta de memoria que necesita el array, hay que declararle. En la declaracin se indica el tipo de datos que contendr el array y la cantidad de elementos. Por ejemplo: int a[7]; Esa instruccin declara un array de siete elementos. Lo que significa que en memoria se reserva el espacio de siete enteros (normalmente 2 o 4 bytes por cada entero). Los elementos del array irn de a[0] a a[6] (hay que recordar que en C el primer elemento de un array es el cero). Hay que tener en cuenta que los arrays contienen una serie finita de elementos, es decir, de antemano debemos conocer el tamao que tendr el array. El valor inicial de los elementos del array ser indeterminado (depender de lo que contenga la memoria que se ha asignado al array, ese valor no tiene ningn sentido) por lo que conviene inicializar los arrays.

(7)

fundamentos de programacin
(Unidad 6) estructuras estticas

(6.3.3) utilizacin de arrays


asignacin de valores El acceso a cada uno de los valores se realiza utilizando un ndice que permite indicar qu elemento del array estamos utilizando. Por ejemplo: a[2]=17; printf(%d,a[2]); a[2] es el tercer elemento del array, se le asigna el valor 17 y ese valor se muestra luego en la pantalla. Para rellenar todos los datos de un array se suelen utilizar bucles, en especial el bucle for. Por ejemplo en el caso de tener que leer 21 notas, gracias a los arrays no necesitamos 21 instrucciones, sino que basta con un bucle con contador que vaya recorriendo cada elemento. Ejemplo (lectura de 21 notas): /* Array de 21 elementos */ int nota[21]; /* Contador para recorrer el array */ int i; for(i=0;i<21;i++) { printf(Escriba la nota %d:,i); scanf(%d,&nota[i]); } Al final del bucle anterior, las notas estarn rellenadas. Por ejemplo con estos valores: componente nota[0] 5 valor nota[1] 6 nota[2] 4 ... ... nota[19] 7 nota[20] 4

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)

1er curso de administracin de sistemas informticos autor: Jorge Snchez www.jorgesanchez.net

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,&nota[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.

(6.3.4) pasar un array como parmetro de una funcin


Los arrays son un elemento muy interesante para utilizar conjuntamente con las funciones. Al igual que las funciones pueden utilizar enteros, reales o caracteres como argumentos, tambin pueden utilizar arrays; pero su tratamiento es diferente. (10)

1er curso de administracin de sistemas informticos autor: Jorge Snchez www.jorgesanchez.net

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 &nota[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 &nota[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,&nota[0]); /* Escribe una direccin de memoria */ printf(%d\n,nota); /* Escribe la misma direccin */ printf(%d\n,&nota); /* De nuevo escribe la misma direccin */ En el ejemplo anterior, la tercera lnea que escribe &nota, denota que &nota 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)

1er curso de administracin de sistemas informticos autor: Jorge Snchez www.jorgesanchez.net

Ejemplo: void prueba(const int x[],int n){


x[0]=4; /* Error no se puede modificar x al usar const */

(6.3.5) algoritmos de bsqueda y ordenacin en arrays


bsqueda en arrays En muchas ocasiones se necesita comprobar si un valor est en un array. Para ello se utilizan funciones que indican si el valor est o no en el array. Algunas devuelven verdadero o falso, dependiendo de si el valor est o no en el array; y otras (mejores an) devuelven la posicin del elemento buscado en el array (o un valor clave si no se encuentra, por ejemplo el valor -1). Los algoritmos de bsqueda son muy distintos dependiendo de si el array est ordenado o no. bsqueda lineal En este caso el array no est ordenado. La funcin de bsqueda busca un valor por cada elemento del array. Para ello el algoritmo recorre todos los elementos del array uno a uno, cuando el valor se encuentra devuelve su posicin. Si se recorre todo el array y el valor no se encuentra, devuelve -1. /* parmetros: vector: Array que contiene todos los valores tamanio: Tamao del mismo valor: valor a buscar */ int busquedaLineal(int vector[], int tamanio, int valor){ int i=0; int enc=0; /* Indica si se ha encontrado el valor */ while (enc==0 && i< tamanio){ if(vector[i]==valor) enc=1; else i++; } if(enc==1) return i; else return -1; } En el caso de que aparezca dos veces el valor buscado en el array y no se encuentre, devuelve la posicin de la primera aparicin.

(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)

1er curso de administracin de sistemas informticos autor: Jorge Snchez www.jorgesanchez.net

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

y ahora aadimos el nmero 4, el resultado ser: 1 2 3 4 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)

1er curso de administracin de sistemas informticos autor: Jorge Snchez www.jorgesanchez.net

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

(6.3.6) arrays multidimensionales


En muchas ocasiones se necesitan almacenar series de datos que se analizan de forma tabular. Es decir en forma de tabla, con su fila y su columna. Por ejemplo:
columna 0 fila 0 fila 1 fila 2 columna 1 columna 2 columna 3 columna 4 columna 5

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)

1er curso de administracin de sistemas informticos autor: Jorge Snchez www.jorgesanchez.net

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

p seala a x, y se representa as:

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

(6.4.2) declaracin de punteros


Un puntero seala a una direccin de memoria. Esa direccin contendr valores de un determinado tipo. Por ello al declarar un puntero hay que indicar de qu tipo es el puntero; o, lo que es lo mismo, el tipo de valores a los que apunta. La sintaxis es: tipo *nombrePuntero; El asterisco indica que lo que tenemos es un puntero. El tipo es el tipo de valores a los que seala el puntero. Ejemplo: int *ptrSuma; Eso significa que ptrSuma es un puntero que podr sealar a variables o valores de tipo int (enteras). char *ptr2; En este caso ptr2 es un puntero que seala a caracteres. int **ptr3; ste es un caso ms enrevesado, ptr3 es un puntero que sealar a punteros que a su vez sealan a enteros.

(6.4.3) operaciones con punteros


Para asignar valores a un puntero muchas veces se utiliza el operador & (ya comentado en los temas anteriores) que sirve para obtener la direccin de una variable. Ejemplo: int *ptrSuma, suma=18; ptrSuma=&suma; Desde la ltima instruccin ptrSuma contendr la direccin de la variable suma; o dicho de otra forma: ptrSuma apunta a la variable suma. Cuando un puntero tiene un determinado valor (apunta a una determinada direccin), a menudo desearemos acceder al contenido de la direccin a la que apunta. Para ello se utiliza el operador *, que permite acceder al contenido del puntero. Ejemplo: int *ptrSuma, suma=18; ptrSuma=&suma; printf(%d,*ptrSuma); /*Escribe 18*/ (20)

1er curso de administracin de sistemas informticos autor: Jorge Snchez www.jorgesanchez.net

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.

(6.4.4) punteros como parmetros de funciones


Un puntero puede utilizarse como parmetro (o argumento) de una funcin, en ese caso basta con indicar el tipo del puntero (int *, char *,...). De hecho, los punteros como parmetros sirven para conseguir pasar una variable por referencia. Hasta ahora la forma de pasar los datos era por valor (excepto en el caso de los arrays). De esa forma, observando el ejemplo: void f(int x){ x=3; } int main(){ int x=8; f(x); printf(%d,x); /* sale 8 y no 3 */ } Aunque f modifica el valor de x, tras la llamada a la funcin, x no ha cambiado. La razn es que la x de la funcin no es la x del main; en realidad es una copia (que no se tiene de hecho que llamar precisamente x). Por ello cuando en la funcin se asigna el nmero 8, se le asigna a la copia; copia que desaparecer al finalizar la funcin, por ello la variable original no vara. Como ejemplo de paso por parmetros, supongamos que queremos calcular el cubo de un nmero. Lo normal es que la funcin que calcula el cubo fuera esta: double cubo(double n){ return n*n*n; } Y en este cdigo: double x=8; double y=cubo(x) (21)

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.

(6.4.5) funciones que devuelven punteros


Es perfectamente posible que una funcin devuelva un puntero. Por ejemplo: int *punteroAlMenor(int array[],int tam){ int *menor=array; /* inicialmente el puntero menor, seala al primer elemento del array*/ int contador=1; while(contador<tam){ if(*menor>array[contador]){ menor=&array[contador]; /* el puntero seala ahora al siguiente elemento ms pequeo */ } contador++; } return menor; } La funcin devuelve un puntero (int *) al elemento ms pequeo del array.

(22)

1er curso de administracin de sistemas informticos autor: Jorge Snchez www.jorgesanchez.net

(6.4.6) aritmtica de punteros


A los punteros se les puede aplicar operaciones aritmticas sin que ello produzca errores de ningn tipo. Pero hay que tener en cuenta que esta aritmtica es un tanto peculiar. De hecho en este programa: int *p; p=180000; /* p apunta a la direccin 18000 de memoria */ printf("%d\n",p); /* Escribe 18000 */ printf("%d",p+2); /* Escribe 18008 */ Es toda una sorpresa la ltima lnea: lo esperable sera que p+2 sumara dos a la direccin que contiene p. Pero le suma 8 (aunque en muchos compiladores sumara 4, debido a las diferencias del tamao de los tipos estndar). De hecho lo que suma son dos veces el tamao de los enteros (se puede saber esta cifra usando sizeof(int) ). Es decir si p apunta a un entero, p+1 apunta al siguiente entero de la memoria. De hecho, la expresin p++ hace que se incremente p para que apunte al siguiente entero en memoria. Lo mismo vale para punteros de cualquier tipo de datos que no sean enteros. Tambin se pueden restar punteros. El resultado es el nmero de bytes que separan aun puntero de otro. Por ejemplo: int *p1, *p2, x=8,y=7; p1=&x; p2=&y; printf(Enteros que se paran a p1 de p2=%d,p2-p1); Esa diferencia es la correspondiente al nmero de posiciones en memoria para enteros que separan a p1 de p2. Es decir, si la diferencia es de 2 significar que hay 8 bytes entre los dos punteros (suponiendo que un entero ocupe 4 bytes).

(6.4.7) punteros y arrays


La relacin entre punteros y arrays es muy directa, ya que los arrays son referencias a direcciones de memoria en la que se organizan los datos. Tanto es as, que se puede hacer que un puntero seale a un array. Por ejemplo: int A[]={2,3,4,5,6,7,8}; int ptr; ptr=A; Esa ltima instruccin hace que el puntero seale al primer elemento del array (observar que no se ha utilizado el &). La instruccin ltima es equivalente a: ptr=&A[0]; (23)

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.

(6.5) cadenas de caracteres


(6.5.1) introduccin
Las cadenas de caracteres son los textos formados por varios caracteres. En C las cadenas (o strings) son arrays de caracteres, pero que tienen como particularidad que su ltimo elemento es el carcter con cdigo cero (es decir \0). En sentido estricto una cadena de C es un puntero al primer carcter de un array de caracteres. Slo que hay un elemento en ese array que tendr el cdigo 0 y marcar as el final del texto. Las cadenas de caracteres es la forma que tiene C de representar textos. Por lo que su uso es imprescindible.

(24)

1er curso de administracin de sistemas informticos autor: Jorge Snchez www.jorgesanchez.net

(6.5.2) declarar cadenas


Las cadenas de caracteres no son exactamente arrays de caracteres, su utilizacin para representacin de textos, obliga a que su manejo sea ms sencillo que el del resto de arrats. Por ello su declaracin puede ser una de las siguientes: char nombre1[]={J,u,,n,\0}; char nombre2[]=Jun; char *nombre3=Jun; Las dos primeras declaraciones, declaran un array cuyo contenido es en ambos casos el texto Jun finalizando con el carcter 0. La segunda definicin crear el texto Jun (con su terminacin en nulo) en algn lugar de memoria, a cuyo primer elemento seala el puntero nombre3. La tercera forma de declarar e inicializar cadenas, puede tener problemas en algunos compiladores (como Dev C++ por ejemplo), ya que la cadena se coloca en zonas de la memoria en las que no se pueden modificar. En esos compiladores es mejor inicializar cadenas utilizando siempre un array (usando la segunda forma en el ejemplo). De otro modo cuando queramos modificar el texto ocurrira un error de ejecucin Al utilizar arrays para guardar cadenas, convienen que stos sean lo suficientemente grandes, de otro modo tendramos problemas ya que al sobrepasar el array invadiramos el espacio de otras variables. Si no queremos dar valores iniciales a la cadena, conviene declararla en forma de array con tamao suficiente. Por ejemplo: char cadena[80]; Lo cual hace que se reserven en memoria 80 caracteres para esa variable. Los punteros que sealan a cadenas se utilizan mucho ya que, puesto que las cadenas finalizan con el delimitador cero, en casi todos los algoritmos con textos, son los punteros los que recorren y operan con los caracteres. char cadena[80]="Esto es una prueba"; char *p=cadena; /* El puntero seala al primer carcter de la cadena */ puts(p); /*escribe: Esto es una prueba */ while (*p!=0){ printf("%c\n",*p); /*Escribe cada carcter en una lnea*/ p++; } (25)

fundamentos de programacin
(Unidad 6) estructuras estticas

(6.5.3) leer y escribir cadenas


Para escribir una cadena de caracteres por la pantalla, basta con utilizar el modificador %s: printf(%s,nombre1); Tambin es posible utilizar el mtodo puts al que se le pasa una cadena. Este mtodo escribe el texto de la cadena y el cambio de lnea. Ejemplo: puts(s); De igual manera se puede leer una cadena por teclado: scanf(%s ,nombre1); Mejor an se puede utilizar la funcin gets que sirve exclusivamente para leer cadenas (es ms aconsejable). Ejemplo: gets(s); No hace falta utilizar el signo &, ya que toda cadena es un array de caracteres y por lo tanto s es la direccin inicial del texto.

(6.5.4) comparar cadenas


La comparacin entre cadenas es problemtica (como lo es tambin la comparacin entre arrays). La razn est en que aunque dos cadenas tengan el mismo contenido, como sus direcciones sern distintas, la comparacin con el operador == saldr falsa. La comparacin de cadenas necesita comparar carcter a carcter o utilizar la funcin strcmp la librera string.h que devuelve 0 si dos cadenas tienen el mismo contenido, -1 si en el orden de la tabla ASCII la primera es menor que la segunda y 1 si la segunda es menor que la primera. Hay que tener en cuenta que strcmp no comprueba las maysculas y que las letras como la ee o las acentuadas causan problemas al comparar el orden alfabtico.

(26)

1er curso de administracin de sistemas informticos autor: Jorge Snchez www.jorgesanchez.net

(6.5.5) funciones y cadenas


En el caso de las funciones que reciben como parmetro cadenas, siempre utilizan punteros (char *) ya que permiten un mejor recorrido de los mismos. Por ejemplo esta funcin se encargara de realizar una copia de una cadena en otra: void copiaCadena(char *cadena1, const char *cadena2){ while(*cadena2!=0){ *cadena1=*cadena2; cadena1++; cadena2++; } *cadena1=0; } La palabra const sirve para indicar al compilador que la cadena2 no puede ser modificada en el interior de la funcin. Es importante poner el delimitador cero al final de la primera cadena (tras haber copia el texto, es la instruccin *cadena1=0). La llamada a esa funcin podra ser: char s1[50]; /*s1 reserva 50 caracteres, eso es importante*/ char s2[]="Prueba"; copiaCadena(s1,s2); puts(s1); /* escribe Prueba */ Una funcin puede devolver un puntero que seale a un carcter (una funcin que devuelve char *), pero si una funcin crea una cadena, al salir de la funcin, esta cadena se elimina. Esto significa que una funcin no debe devolver la direccin de una cadena creada dentro de la funcin.

(6.5.6) arrays de cadenas


Ya se ha comentado que una cadena es un array de caracteres en el que hay delimitador de fin de cadena que es el cdigo cero . Luego todo lo comentado para los arrays y los punteros vale tambin para las cadenas. La declaracin: char *s[10]; Declara un array de 10 punteros a caracteres (10 cadenas). Para inicializar con valores: char *s[4]={"Ana","Pablo","Julin","Roberto"}; puts(s[2]); /* Escribe Julin */ (27)

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.

(6.5.7) funciones de uso con cadenas


funciones de manipulacin de caracteres Estn en la librera ctype.h y trabajan con caracteres, pero son muy tiles para usar en algoritmos para cadenas. Las funciones son:
prototipo de la funcin int isdigit(int carcter) int isalpha(int carcter) int isalnum(int carcter) int islower(int carcter) int isupper(int carcter) int tolower(int carcter) int toupper(int carcter) int isspace(int carcter) int iscntrl(int carcter) descripcin Devuelve verdadero si el carcter es un dgito de 0 a 9 Devuelve verdadero (un valor distinto de 0) si el carcter es una letra (del alfabeto ingls) Devuelve verdadero si el carcter es una letra o un nmero. Devuelve verdadero si el carcter es una letra minscula (segn el alfabeto ingls). Devuelve verdadero si el carcter es una letra mayscula (segn el alfabeto ingls). Convierte el carcter a minsculas Convierte el carcter a maysculas Devuelve verdadero si el carcter es el espacio en blanco Devuelve verdadero si el carcter es de control

(28)

1er curso de administracin de sistemas informticos autor: Jorge Snchez www.jorgesanchez.net

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.

double atoi(char *s)

double atol(char *s)

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.

char * strchr(char *s1, int carcter)

char * strrchr(char *s1, int carcter)

(29)

fundamentos de programacin
(Unidad 6) estructuras estticas

prototipo de la funcin char * strstr(char * s1, char * s2)

int * strlen(char * s) char *strtok(char *s1, char *s2);

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)

1er curso de administracin de sistemas informticos autor: Jorge Snchez www.jorgesanchez.net

(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.

(6.6.3) acceso a los miembros de una estructura


Los datos de las estructuras a veces se llaman campos (campo nombre, campo dni, etc...). Para poder cambiar o leer los datos de un campo de una estructura, se debe poner el nombre de la variable de estructura, un punto y el nombre del dato que queremos ver. Ejemplo: strcpy(pepe.nombre,Pepe); strcpy(pepe.apellidos,"Villegas Varas); pepe.edad=12;

(6.6.4) estructuras dentro de estructuras


Los miembros de una estructura pueden ser variables de estructura. Por ejemplo: typedef struct{ char tipoVia; char nombre[50]; int numero; int piso; char puerta[10]; } Direccion;

(32)

1er curso de administracin de sistemas informticos autor: Jorge Snchez www.jorgesanchez.net

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;

(6.6.5) operaciones con estructuras


asignacin Las estructuras pueden utilizar la operacin de asignacin para que dos variables de estructura copien sus valores. Por ejemplo: Persona pepe,jaime; strcpy(pepe.nombre,Pepe); strcpy(pepe.apellidos,"Villegas Varas); pepe.edad=12; (33)

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.

(6.6.6) arrays y punteros a estructuras


arrays Se pueden crear arrays de estructuras. Antes hemos definido el siguiente tipo de estructura: typedef struct{ char nombre[25]; char apellidos[50]; char dni[10]; int edad; }Persona;

(34)

1er curso de administracin de sistemas informticos autor: Jorge Snchez www.jorgesanchez.net

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.

(6.6.7) estructuras y funciones


Una estructura puede pasar a una funcin un elemento de la estructura (el nombre de una persona por ejemplo), la estructura completa o un puntero a una estructura. Imaginemos que declaramos la siguiente persona: Persona pedro; strcpy(pedro.nombre,"Pedro"); strcpy(pedro.apellidos,"Herrera Quijano"); strcpy(pedro.dni,"12345678W"); pedro.edad=23; En el cdigo se observa que Pedro tiene 23 aos. Supongamos que creamos una funcin para subir la edad de una persona a un ao. (35)

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)

1er curso de administracin de sistemas informticos autor: Jorge Snchez www.jorgesanchez.net

(6.8) campos de bits


Los campos de bits son estructuras que sirven para almacenar bits. Los miembros de esta estructura son valores unsigned o int. En cada miembro se indica los bits que ocupa por ejemplo: struct color{ unsigned rojo:2; unsigned verde:2; unsigned azul:2; unsigned transpar:3; }; Como en las estructuras, se puede definir el tipo con typedef: typedef{ unsigned unsigned unsigned unsigned } Color;

rojo:2; verde:2; azul:2; transpar:3;

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)

1er curso de administracin de sistemas informticos autor: Jorge Snchez www.jorgesanchez.net

Ejemplo completo de uso de enum: typedef enum{ ESO1, ESO2, ESO3, ESO4, FP1, FP2, BACH1, BACH2, PREU }Clases;

int main(){ Clases c1; char *nombreClases[]={

"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)

También podría gustarte