estructuras union enum lenguaje c

18

Click here to load reader

Upload: joshram

Post on 23-Nov-2015

47 views

Category:

Documents


0 download

DESCRIPTION

Uso de las estructuras de datos en Lenguaje C

TRANSCRIPT

  • Lenguaje de Programacin: C Invierno 2012

    DICIS-Universidad de Guanajuato [email protected]

    Estructuras, uniones y tipos de datos definidos por el usuario.

    Estructuras.

    Las estructuras ( struct ) son agrupaciones de una o ms variables de tipos posiblemente diferentes,

    agrupadas bajo un mismo nombre. Esto permite un manejo ms cmodo de la informacin cuando sta est

    relacionada. Las struct son estructuras de datos similares a los registros ( record ) de Pascal. La forma general de definicin es:

    struct tipo_estructura {

    tipo miembro_1;

    tipo miembro_2;

    .

    tipo miembro_n;

    } Lista_variables_estructura;

    donde tipo_estructura ( que ser el nombre de la estructura ) Lista_variables_estructura ( que es una lista

    de las variables que sern de este tipo de estructura ) pueden omitirse pero no ambos. Las estructuras

    ayudan a agrupar informacin relacionada como los datos de una cdula de identidad, las coordenadas de un

    punto, etc.

  • Lenguaje de Programacin: C Invierno 2012

    DICIS-Universidad de Guanajuato [email protected]

    Ejemplos de declaracin de estructuras

    struct datos {

    char nombre[20];

    char direccion[20];

    long int NumCedula;

    char sexo;

    };

    /* Veamos ahora como declaramos una variable de tipo struct datos. Aqu tenemos a a como una estructura de este tipo y b como un array de 5 estructuras de este tipo*/

    struct datos a,b[5];

    Las estructuras tambin pueden estar anidadas. Esto quiere decir que un elemento de una estructura puede

    ser a su vez otra estructura.

    Veamos un ejemplo:

    struct fecha {

    int dia;

    int mes;

    int anio;

    };

  • Lenguaje de Programacin: C Invierno 2012

    DICIS-Universidad de Guanajuato [email protected]

    struct persona {

    char nombre[20];

    struct fecha nacimiento;

    };

    struct persona p;

    Aqu vemos que la estructura persona contiene un elemento que es del tipo de estructura fecha.

    OJO: Como vimos en la definicin, tambin pueden declararse las variables que sern de un tipo de

    estructura desde el momento de la declaracin haciendo algo como:

    struct persona {

    char nombre[20];

    struct fecha nacimiento;

    } p, q ; // Esto declara 'p' y 'q' de tipo struct persona"

    Cmo se referencian estas variables?. Muy bien, los elementos individuales de una estructura se referencian

    utilizando el operador punto ( . ) entre el nombre de la variable de tipo estructura y el nombre del miembro

    de la estructura. A los elementos de una estructura se les denomina miembros.

    Continuando con las estructuras de los ejemplos anteriores, se pueden tener las siguientes referencias a

    miembros:

    a.nombre // Referencia la variable nombre de la estructura datos llamada a

  • Lenguaje de Programacin: C Invierno 2012

    DICIS-Universidad de Guanajuato [email protected]

    a.direccin // Referencia la variable direccin de la estructura datos llamada a

    b[2].NumCedula // Referencia la variable NumCedula del segundo elemento del arreglo

    // de tipo struct datos llamado b

    p.nombre

    p.nacimiento.dia // Estos casos referencian un elemento de una struct fecha dentro

    p.nacimiento.mes // de la struct persona. Analcenlo.

    Funciones y estructuras.

    1 .- Paso por valor de miembros de una estructura a una funcin.

    Se realiza como si fueran variables simples. Por ejemplo, para pasar por valor el miembro a.NumCedula:

    void funcion f1(int x); /*declaracin de la funcin prototipo*/

    f1(a.NumCedula); /* llamada a la funcin */

    void f1(int x) { /* definicin de la funcin */

    ...

    }

    2.- Paso por direccin ( lo mismo que por referencia ) de miembros de una estructura a una funcin.

    Se realiza como si fueran variables simples. Por ejemplo, para pasar por referencia el miembro

    a.NumCedula:

  • Lenguaje de Programacin: C Invierno 2012

    DICIS-Universidad de Guanajuato [email protected]

    void funcion f1(int *) /*declaracin de la funcin prototipo*/

    f1(&a.codigo); /* llamada a la funcin */

    void f1(int *x) { /* definicin de la funcin */

    }

    Hay que tener en cuenta que si lo que se pasa a una funcin es un miembro de una estructura que sea un

    arreglo, ste siempre se pasa por direccin ( ya que el nombre del arreglo es la direccin del primer

    elemento del mismo ).

    3.- Paso por valor de estructuras completas a funciones.

    En el siguiente ejemplo, suma es una funcin que recibe dos estructuras pasadas por valor y a su vez

    devuelve una estructura.

    struct vector {

    int x,y,z;

    };

    struct vector (struct vector v1, struct vector v2);

    void main() {

    struct vector v1,v2,v3;

  • Lenguaje de Programacin: C Invierno 2012

    DICIS-Universidad de Guanajuato [email protected]

    ...

    v3=suma(v1,v2);

    ...

    }

    struct vector suma(struct vector v1, struct vector v2) {

    v1.x+=v2.x;

    v1.y+=v2.y;

    v1.z+=v2.z;

    return (v1);

    }

    4.- Paso por referencia de estructuras completas a funciones.

    Cuando las estructuras son muy grandes es ms eficiente pasarlas por direccin. En ese caso se utilizan

    punteros a estructuras para realizar la comunicacin. Para acceder a los miembros de la estructura debe

    utilizarse la combinacin de los operadores * y punto. Sin embargo el operador punto tiene ms precedencia

    que * siendo necesario el uso de parntesis para asegurar que se aplique primero * y despus punto.

    Tambin puede utilizarse el operador -> para acceder a los miembros de una estructura referenciada por un

    puntero y de hecho este es la forma ms usada en la actualidad.

    #include

    struct pareja {

    int a,b;

    };

  • Lenguaje de Programacin: C Invierno 2012

    DICIS-Universidad de Guanajuato [email protected]

    void f1(struct pareja *q);

    void main() {

    struct pareja p = { 13, 17 } /* inicializacin de los miembros*/

    f1(&p);

    printf("a:%d y b:%d\n", p.a, p.b); /* a: 14 y b:18 */

    }

    void f1(struct pareja *q) {

    q->a++; /* equivalente a (*q).a++ pero ms usado */

    q->b++;

    return; // Este return no retorna nada ya que la funcin es void.

    // En este caso no era necesario su uso pero recuerden que return tambin

    // se usa para finalizar una funcin inmediatamente.

    }

    En este ejemplo tambin se observ como se inicializan los elementos de una estructura: con {ele1,

    ele2,...,elen}; igual que en los arreglos. El primer elemento inicializa la primera variable de la estructura, el segundo elemento a la segunda variable y as sucesivamente. As, si usamos la estructura datos que

    mencionamos al principio, una forma de inicializarla sera algo como:

    struct datos a = {Tony, Maracay, 8765432, 'M'};

    COMENTARIO ADICIONAL: Existe una forma en C de acceder a los bits de una variable de forma

    independiente sin tener que hacer operaciones a nivel de stos. Esta forma de acceso est ligada al uso de

    estructuras. Si lo necesita, puede buscar ms informacin acerca de este tema o preguntarme.

  • Lenguaje de Programacin: C Invierno 2012

    DICIS-Universidad de Guanajuato [email protected]

    Uniones

    Las uniones son otro tipo de datos que pueden ser usados en C y aunque tienen una sintaxis similar a las

    estructuras se diferencian de stas en que sus miembros comparten almacenamiento. Esto quiere decir que

    una variable unin define a un conjunto de valores alternos que se almacenan en una porcin compartida de

    memoria. Es una versin C de los registros variantes de otros lenguajes como Pascal.

    El compilador asigna una porcin de almacenamiento que pueda acomodar al ms grande de los miembros

    especificados. La notacin para acceder a un miembro de la unin es idntica a la que se emplea para

    acceder a un miembro de una estructura. Un ejemplo de unin es el siguiente:

    union simple {

    char ch;

    int i;

    };

    union simple a;

    // podemos acceder a las variables de la unin haciendo:

    a.ch = a;

    ...

    a.i = 3;

    Como ya comentamos, las uniones comparten el almacenamiento, o sea, que slo se reserva espacio en

    memoria como para almacenar la ms grande de las variables que en este caso es un int por lo que son dos

    bytes. Dentro de esos dos bytes se almacenarn las variables pero, como usted ya habr analizado, slo

    puede mantenerse el valor de una de ellas. O sea que en el ejemplo anterior, al usar a.i, a.ch se pierde.

    Veamos otro ejemplo:

  • Lenguaje de Programacin: C Invierno 2012

    DICIS-Universidad de Guanajuato [email protected]

    union ejemplo {

    long int cedula;

    char nombre[10];

    char Nacimiento[12];

    };

    Esta variable slo ocupar 12 bytes que es el mayor dato que puede contener y mantendr en cada momento

    slo a una de ellas.

    OJO: Es muy importante que sepan que una unin slo puede ser inicializada con un valor del tipo de su

    primer miembro.

    union ejemplo a={8765432};

    Uso de sizeof para asegurar la portabilidad.

    Al principio del curso, y tambin en la primera parte de punteros, comentamos el operador sizeof(). El uso

    de este operador es de gran importancia a la hora de calcular el tamao real de las variables, el cual puede

    variar de maquina en maquina. Por ejemplo, en MSDOS:

    char c;

    sizeof(int); //Retorna 2, ya que int ocupa dos bytes

    sizeof(c); // retorna 1 ya que c es de tipo char y ocupa un byte

  • Lenguaje de Programacin: C Invierno 2012

    DICIS-Universidad de Guanajuato [email protected]

    mientras que en Linux, aunque los char son del mismo tamao, sizeof(int) retorna 4.

    En todo caso, hice nuevamente referencia al operador sizeof debido a que uno de sus mayores usos es en el

    clculo de tamaos de variables definidas por el usuario tales como estructuras y uniones. Supongamos que

    se necesita guardar datos en un arreglo que ser creado dinmicamente con malloc y que este arreglo

    contendr, por ejemplo, 27 elementos de un tipo de estructura que ha sido creada por nosotros. Supongamos

    tambin que la estructura es la siguiente:

    struct tamao {

    char ch;

    int i;

    long int li;

    float f;

    double d;

    long double ld;

    char cad[10];

    int mat[10][15];

    } me;

    Para poder reservar memoria con malloc de forma directa deberamos primero calcular cuantos bytes ocupa

    esta estructura que en MSDOS sera: ch = 1, i = 2, li = 4, f = 4, d = 8, ld = 10, cad = 10 y mat = 2*10*15 =

    300. Sumado todo da 339 bytes por estructura que luego multiplicamos por 27 para obtener el espacio total

    requerido = 9153 bytes. As, haramos:

    struct tamao *pe;

    pe = (struct tamao *)malloc(9153);

  • Lenguaje de Programacin: C Invierno 2012

    DICIS-Universidad de Guanajuato [email protected]

    y tendramos que hacer los distintos clculos para las diferentes plataformas. Usando sizeof slo haramos:

    pe = (struct tamao *)malloc(27*sizeof(me));

  • Lenguaje de Programacin: C Invierno 2012

    DICIS-Universidad de Guanajuato [email protected]

    Tipos de datos definidos por el usuario.

    C soporta la creacin de nuevos nombres de tipos de datos. Esto se realiza utilizando la palabra reservada

    typedef:

    typedef tipo nombre

    Ejemplos:

    Con tipos simples:

    typedef int ENTERO

    typedef float REAL

    ENTERO a,b; // Define a y b como de tipo ENTERO, o sea, int.

    REAL c;

    Con tipos estructurados:

    typedef struct{

    int dia;

    int mes;

    int anio;

    } FECHA;

  • Lenguaje de Programacin: C Invierno 2012

    DICIS-Universidad de Guanajuato [email protected]

    FECHA a;

    incluso si la estructura ya est creada:

    struct test {

    int i;

    char ch;

    char cad[10];

    }

    podemos usar:

    typedef struct test MiNuevoTipo;

    ...

    MiNuevoTipo a;

  • Lenguaje de Programacin: C Invierno 2012

    DICIS-Universidad de Guanajuato [email protected]

    Enumeraciones ( enum )

    Una enumeracin, es un conjunto de constantes enteras con nombre, que especifica todos los valores vlidos

    que una variable de este tipo puede tener. Estos valores son listados explcitamente por el programador. Las

    constantes representan los valores que pueden ser asignados a las variables declaradas del tipo del enum. Su

    forma de declaracin es:

    enum nombre { val1,val2,...,valn }; donde valn son identificadores de constantes.

    enum etiqueta { lista_de_enumeraciones } lista_de_variables;

    En el primer caso, val1 es un identificador que tendr un valor de cero, val2 un valor de 1 y as

    sucesivamente pero se pueden asignar otros valores indicndolo en la enumeracin:

    enum nombre {val1=0, val2=10, val3=13,... };

    Puede suceder incluso que ms de una constante de enumeracin tenga el mismo valor entero.

    enum color{rojo=-1, azul, amarillo, verde, negro=0};

    Las variables de enumeracin pueden utilizarse como enteros; asignarles valores, compararlas, etc.

    Vemos un ejemplo:

  • Lenguaje de Programacin: C Invierno 2012

    DICIS-Universidad de Guanajuato [email protected]

    enum moneda { medio, real, bolivar };

    ...

    enum moneda dinero;

    Entonces podramos decir:

    dinero = medio;

    if (dinero == medio ) printf(Es un medio\n);

    La clave para entender las enumeraciones es que cada uno de los smbolos corresponde a un valor

    entero. De esta forma, puede usarse en cualquier expresin entera. Por ejemplo:

    printf(El valor de un medio es %i, medio);

    Perfectamente vlido.

    Como ya comentamos, a menos que se inicialice de otro modo, el valor del primer smbolo ser cero, el del

    segundo 1 y as sucesivamente. Por lo tanto en el ejemplo anterior:

    printf(%i %i, medio, bolivar);

    imprimir 0 2 en la pantalla.

    Tambin dijimos que se pueden especificar valores en la inicializacin:

    enum moneda { medio=25, real=50, bolivar=100 };

  • Lenguaje de Programacin: C Invierno 2012

    DICIS-Universidad de Guanajuato [email protected]

    , por ejemplo, en:

    enum color { amarillo, azul=10, verde, rojo, negro=100 };

    tendremos que, segn la inicializacin: amarillo=0, azul=10, verde=11, rojo=12 y negro =100.

    No se puede escribir ms que el valor entero de la variable enum lo que quiere decir que no se puede

    escribir su nombre. Recuerde, NO son cadenas. Son slo nombres de enteros.

    dinero = real;

    printf(%s, dinero); // Esto est mal.

    Lo que si se puede hacer es pedir un entero y asignrselo a una enumeracin.

    Los tipos enumerados NO aportan capacidades nuevas al lenguaje, pero aumentan la claridad de algunos

    programas. Veamos un caso tpico de su uso ( en conjunto con arreglos de cadenas ).

    enum colores {negro, azul, verde, cyan, rojo, magenta, marron, amarillo=14, blanco };

    char *nombreColores[]={

    negro",

    "azul",

    "verde",

    "cyan",

  • Lenguaje de Programacin: C Invierno 2012

    DICIS-Universidad de Guanajuato [email protected]

    "rojo",

    "magenta",

    "marron",

    amarillo,

    blanco

    };

    /* Aunque por supuesto en este caso el ndice del amarillo y blanco no corresponden con los valores

    en enum lo cual presentar errores en el siguiente cdigo. Sern comentados */

    printf("Introduzca un numero de color: ");

    scanf("%i",&i);

    color = i;

    printf("El numero del color es %i\n",color);

    switch(color) {

    case negro: printf("negro = %s\n",nombreColores[negro]);

    printf("%s\n",nombreColores[color]); // Anlogo a nombreColores[negro]

    break;

    case azul: printf("azul = %s\n",nombreColores[azul]);

    printf("%s\n",nombreColores[color]);

    break;

    case verde: printf("verde = %s\n",nombreColores[verde]);

    printf("%s\n",nombreColores[color]);

    break;

    case cyan: printf("cyan = %s\n",nombreColores[cyan]);

  • Lenguaje de Programacin: C Invierno 2012

    DICIS-Universidad de Guanajuato [email protected]

    printf("%s\n",nombreColores[color]);

    break;

    case rojo: printf("rojo = %s\n",nombreColores[rojo]);

    printf("%s\n",nombreColores[color]);

    break;

    case magenta: printf("magenta = %s\n",nombreColores[magenta]);

    printf("%s\n",nombreColores[color]);

    break;

    case marron: printf("marron = %s\n",nombreColores[marron]);

    printf("%s\n",nombreColores[color]);

    break;

    /* Para los siguientes casos, los valores de color no estn definidos dentro de los permitidos por el arreglo de cadenas ( aunque si por el enum ). Por tal hecho, al tratar de

    imprimir la cadena del arreglo correspondiente, imprimir lo que encuentre en ese punto de

    memoria hasta conseguir el caracter nulo */

    case amarillo: printf("amarillo = %s\n",nombreColores[amarillo]);

    printf("%s\n",nombreColores[color]);

    break;

    case blanco: printf("blanco = %s\n",nombreColores[blanco]);

    printf("%s\n",nombreColores[color]);

    break;

    default: printf("Ese color no lo conozco\n");

    }