SlideShare uma empresa Scribd logo
1 de 16
Baixar para ler offline
Ingeniería Técnica Industrial
                                                           Fundamentos de Informática



                                                Tema 8. Estructuras de Datos Complejas



TEMA 8. Estructuras de Datos Complejas

8.1 Vectores Estáticos
   Con las variables que conocemos hasta ahora, ¿ES POSIBLE
almacenar la nota de todos los alumnos en UNA SOLA VARIABLE ?



                                      NO


                              Necesitamos algo así:

              Vble
              5.6    7   3.9               ...               6.2


   Esta variable es un vector estático o array          colección de variables
del mismo tipo que están almacenados en posiciones contiguas de
memoria y que se referencian utilizando un nombre (que es común
para todos los datos) y un índice (que indica la posición del dato dentro
de todo el conjunto). La dirección más baja corresponde al primer
elemento y la más alta al último.
   Ejemplo:

                     Notas
              5.6    7   3.9              ...                6.2
     Indice    0     1    2                                  Max-1




   de modo que la nota del 3er alumno es: Notas[2]




                                                                        Página 1 de 16
Ingeniería Técnica Industrial
                                                             Fundamentos de Informática



                                                  Tema 8. Estructuras de Datos Complejas



8.1.1 Vectores o Arrays unidimensionales

     Gráficamente:     Vble 5        7     3              ...                 6
                      Indice    0    1     2                              tamaño-1


   El formato general para declarar un array unidimensional es
   tipo nombre[tamaño];

   Al declarar el array, se indica entre corchetes el número de elementos
que como máximo va a tener. Estos elementos serán del tipo indicado.
   Ejemplo:
   1. Declarar una variable capaz de almacenar las notas de 50 alumnos:
    float NOTAS[50];

   2. Suponiendo el vector relleno, mostrar las notas de todos los alumnos:
                               ¿ Podría ser i <= 50 ?
   for (i = 0; i < 50; i++)
     printf(“La nota del alumno %i es %.2f n”, i+1, NOTAS[i]);
                                                                     ¿ Por qué?
   3. ¿Cuál es la nota media de la clase?
   float MEDIA, TOTAL = 0;
   for (i = 0; i < 50; i++)
     TOTAL = TOTAL + NOTAS[i];
   MEDIA = TOTAL / 50;

   Con respecto a los arrays debemos tener en cuenta lo siguiente:
   • En C todos los arrays usan 0 como índice del primer elemento.
   • El C permite indexar un array por encima del nº de elementos que
     contiene   no indica ningún mensaje de error en la compilación.
   int main(void){
     int edad[20], i;
     for (i = 1; i <= 20; i++) { /* OJO aquí hay un fallo */
       printf(“Dame la edad de la persona nº %i n”, i);
       scanf(“%i”, &edad[i]);
     } 1. Error1: El índice del elemento 1º es el 0 (no el 1).
   }    2. Error2: El último elemento es edad[19] (no edad[20]).
             Al compilar no da error pero durante la ejecución, la ultima edad se
        introduce en la zona de memoria siguiente a la tabla, donde puede que
        haya alguna variable o parte del código binario del programa.

                                                                          Página 2 de 16
Ingeniería Técnica Industrial
                                                           Fundamentos de Informática



                                                Tema 8. Estructuras de Datos Complejas



8.1.2 Vectores o Arrays multidimensionales
   El formato general de una declaración de array multidimensional es:
   tipo nombre[tamaño1][tamaño2]…[tamañoN];

   El más usado es el array bidimensional o matriz (vector de vectores).
   Ej: Almacenar la temperatura media de cada mes, durante 5 años
   (de 2001 a 2005): años meses
    float TEMP_MEDIA[5][12];

   Mostrar la temperatura media de cada mes, para todos los años:
   for (int agno = 0; agno < 5; agno++)             Fijamos el año
   { printf(“En %i, las temperaturas fueron: n”, 2001 + agno);
      for (mes = 0; mes < 12; mes++)                 Nos movemos por
         printf(“En el mes %i, %.2f grados n”,
                 mes + 1, TEMP_MEDIA[agno][mes]); los meses de ese año
   }
   En los arrays bidimensionales el indice 1º indica la fila y el 2º la columna
   Ejemplo: almacenar en un array de 10 x 10 la tabla de multiplicar
   int main(void)
   { int i, j, tabla[10][10];
     for (i = 0; i < 10; i++)
     { for (j = 0; j < 10; j++)
         tabla[i][j] = (i + 1) * (j + 1);
     }
   }
   Ej: Almacenar la temperatura media de cada día, de cada mes, para 5 años
   (de 2001 a 2005): años meses días
    float TEMPERATURA[5][12][30];

   Mostrar la temperatura media de cada mes y año, para todos los años:
   float media_mes, media_agno;
   for (int agno = 0; agno < 5; agno++)               Fijamos el año
   { media_agno = 0;
     printf(“En %i, las temperaturas fueron: n”, 2001 + agno);
     for (mes = 0; mes < 12; mes++)     Nos movemos por los meses de ese año
     { media_mes = 0;
                                            Recorremos los 30 días de
       for (dia = 0; dia < 30; dia++)
                                            ese mes y ese año
         media_mes = media_mes + TEMPERATURA[agno][mes][dia];
       media_mes = media_mes / 30;
       printf(“En el mes %i, %.2f grados n”, mes + 1, media_mes);
       media_agno = media_agno + media_mes;
     }
     media_agno = media_agno / 12;
     printf(“En %i, la media fue %.2f n”, 2001 + agno, media_agno);
   }

                                                                        Página 3 de 16
Ingeniería Técnica Industrial
                                                          Fundamentos de Informática



                                               Tema 8. Estructuras de Datos Complejas



8.1.3 Inicialización de arrays (indicando y sin indicar el tamaño)


   El formato general de una inicialización de un array es el siguiente:
   tipo nombre[tamaño1]…[tamañoN] = { valor1, valor2, ..., valorN };



   C permite la inicialización de los arrays globales y los locales static:
   int i[5] = { 0, 1, 4, 9, 16 };
   int i[] = { 0, 1, 4, 9, 16 }; /* sin indicar el tamaño */



   Si no se indica el tamaño, se crea un array tan grande como para
albergar todos los datos indicados (es más cómodo).


   Las declaraciones anteriores son equivalentes a esta otra:
   int i[5];
   i[0] = 0;   i[1] = 1;    i[2] = 4;    i[3] = 9;     i[4] = 16;



   Los arrays multidimensionales se inicializan de la misma manera (se
deben indicar todas las dimensiones excepto la de más a la izquierda):
       Indicando el tamaño                     Sin indicar el tamaño
int datos[3][2] = {1,1, 2,4, 3,9}; int datos[][2] = {1,1, 2,4, 3,9};

int datos[3][2] = {    1, 1,            int datos[][2] = { 1, 1
                       2, 4,                                    2, 4,
                       3, 9 };                                  3, 9 };
int datos[3][2];
datos[0][0] = 1;    datos[0][1] = 1;
datos[1][0] = 2;    datos[1][1] = 4;
datos[2][0] = 3;    datos[2][1] = 9;




                                                                       Página 4 de 16
Ingeniería Técnica Industrial
                                                        Fundamentos de Informática



                                             Tema 8. Estructuras de Datos Complejas




8.2 Cadenas o vector de caracteres
   Una cadena o vector de caracteres (strings) es un vector que contiene
en cada celda un carácter del código ASCII.
   En C una cadena se implementa mediante un vector de caracteres
terminado en un nulo (‘0’) que indica el final de la cadena            Hay que
contar con él, a la hora de pensar en el tamaño del vector.
   char cadena[11]; /* puede guardar una cadena de 10 caracteres */

   Aunque C no tiene un tipo de datos string, sí que permite constantes
de cadenas. Una constante de cadena es una lista de caracteres
encerrada entre comillas dobles (“).
   “Bienvenidos”
   “Pulsa una tecla para continuar”

   No se necesita añadir el nulo ('0') manualmente en el final de las
constantes de cadenas, el compilador hace esto automáticamente.

8.2.1 Inicialización de cadenas
   Los arrays de caracteres permiten una inicialización abreviada:
   char nombre[tamaño] = “cadena”;

   El compilador automáticamente añade el terminador nulo:
   char saludo[5] = “hola”;
   char saludo[] = “hola”;      // sin indicar el tamaño
   char saludo[5] = { ‘h’, ‘o’, ‘l’, ‘a’, ‘0’ };         // mas incómodo



   Consideraciones a tener en cuenta al trabajar con cadenas:
   1. No se pueden asignar cadenas con el operador =           usar strcpy()
   2. No se pueden comparar cadenas con el operador ==           usar strcmp()
   3. No se puede asignar a una cadena un valor con el operador =
      salvo en la declaración de la misma.
   4. Para leer desde teclado cadenas que contengan espacios en
      blanco usaremos la función gets( ) ya que scanf( ) no lee espacios.

                                                                     Página 5 de 16
Ingeniería Técnica Industrial
                                                                     Fundamentos de Informática



                                                          Tema 8. Estructuras de Datos Complejas



    Para trabajar con cadenas, C dispone de la librería string.h:
Prototipo de función                          Acción:

char *strcpy(char *c1, const char *c2)        Copia la cadena c2 sobre la cadena c1.
char *strcat(char *c1,const char *c2)         Concatena la cadena c1 con la cadena c2
char *strchr(const char *c1, int ch1)         Busca el carácter ch1 en la cadena c1.
                                              Devuelve un puntero a la 1ª ocurrencia de
                                              ch1 en c1. Si no lo encuentra devuelve NULL.
int strcmp(const char *c1, const char *c2)    Compara la cadena c1 con la cadena c2.
                                              Devuelve un < 0 si c1 < c2; un > 0 si c1 > c2 y
                                              0 si c1 es igual a c2.
int strlen(const char *c1)                    Devuelve la longitud de la cadena c1 sin
                                              contar el terminador nulo ('0').
char *strupr(char *c1)                        Convierte la cadena c1 a mayúsculas.
char *strlwr(char *c1)                        Convierte la cadena c1 a minúsculas
char *strset(char *c1,int ch1)                Rellena toda la cadena c1 con el carácter ch1
char *strstr(const char*c1, const char *c2)   Encuentra la 1ª coincidencia de la subcadena
                                              c2 dentro de c1. Da NULL si no la encuentra.
    Ejemplo:
    #include <stdio.h>                  // printf(), scanf()
    #include <conio.h>                  // getch()
    #include <string.h>                 // strcpy(), strcmp(), strcat(), strlen()

    int main(void) {
        char nombre[30], cadena[80];
        printf(“Dime tu nombre:”);
        gets(nombre); /* scanf(“%s”,…) no lee espacios en blanco */
        strcpy(cadena, nombre);
        if (strcmp(nombre, cadena) == 0)
          printf(“Las cadenas son iguales”);
        printf(“mi nombre es %s n”, nombre);
        strcat(cadena,” es listo”); // concatena 'es listo' a cadena
        printf(“%s”, cadena);
        printf(“La frase tiene %i caracteres n”, strlen(cadena));
        strcpy(nombre, ””); // nombre[0] = '0' (borra la cadena)
        getch();
        return 0;
    }

                                                                                  Página 6 de 16
Ingeniería Técnica Industrial
                                                           Fundamentos de Informática



                                                Tema 8. Estructuras de Datos Complejas



     Para crear un array de cadenas, se usa una matriz de caracteres, en la que
el tamaño del índice izquierdo determina el número de cadenas a almacenar y
el tamaño del derecho especifica la longitud máxima de las cadenas a guardar.
   int main(void) {
     int i;
     char direcciones[10][50];
     for (i = 0; i < 10; i++) {
       printf(“Introduce la dirección nº %i:”, i + 1);
       scanf(“%s”, direcciones[i]);
     }
     for (i = 0; i < 10; i++)
       printf("La dirección nº %i es: %sn", i + 1, direcciones[i]);
     getch();
     return 0;
   }
   No hace falta poner el & en el scanf ya que las sentencias:
   scanf(“%s”, direcciones[i]);
   scanf(“%s”, &direcciones[i][0]);

   son equivalentes: devuelven un puntero al elto 1º del array de índice i.
    En C, el nombre de un array es un puntero al primer elemento del
array. En los de 2 dimensiones, al indicar sólo el primer índice, es un
puntero al primer elemento de dicho índice.
   int main(void){                              Programa que lee 20 líneas
     int i, vocal[5] = {0, 0, 0, 0, 0};         de texto (de 80 caracteres)
     char frase[20][81], vocales[]=”aeiou”;     por teclado y visualiza por
     for(i = 0; i < 20; i++){                   pantalla aquellas líneas que
                                                empiezan por vocal, y un
       printf(“Introduzca frase nº %d: “, i);
                                                resumen indicando el nº de
       gets(frase[i]); // gets(&frase[i][0])
                                                líneas que empiezan por
     }
                                                cada vocal
     for(i = 0; i < 20; i++){
       switch ( toupper(frase[i][0]) ) {
         case ‘A’: vocal[0]++; printf(“%sn”, frase[i]); break;
         case ‘E’: vocal[1]++; printf(“%sn”, frase[i]); break;
         case ‘I’: vocal[2]++; printf(“%sn”, frase[i]); break;
         case ‘O’: vocal[3]++; printf(“%sn”, frase[i]); break;
         case ‘U’: vocal[4]++; printf(“%sn”, frase[i]);
       }
     }
     for (i = 0; i < 5; i++)
       printf(“%i frases empiezan por %c n”, vocal[i], vocales[i]);
     return 0;
   }

                                                                        Página 7 de 16
Ingeniería Técnica Industrial
                                                                 Fundamentos de Informática



                                                      Tema 8. Estructuras de Datos Complejas




8.3 Paso de cadenas y arrays a funciones
    Para pasar un array completo como argumento a una función, en la
llamada a la función sólo se pone el nombre del array (sin índice ni [ ]).
  Si queremos pasar un único elemento a una función, se pondrá el
nombre y entre corchetes el indice (nombre_array[índice_elemento]).
   Los arrays se pasan siempre por referencia a una función: todos los
cambios realizados a la tabla en la función afectan a la tabla original:
   void ver(char c[20], int tope);       void ver(char c[20], int tope)
   void cambia(char c[20], int salto);   { int i;
   int main(void) {                          for(i =0; i < tope; i++)
   char letras[20];                            printf("%c", c[i]);
   int i, j =10;                             printf("n");
   for (i = 0; i < 20; i++)              }
       letras[i] ='a' + i;
   ver(letras, j);                       void cambia(char c[20], int salto)
   cambia(letras, 5);                    { int i;
   ver(letras, j);                           for(i = 0; i < 20; i++)
   return 0;                                   c[i] = c[i] + salto;
   }                                     }
   Al ejecutar el programa, el resultado mostrado es el siguiente:
   abcdefghij
   fghijklmno

   Para pasar arrays multidimensionales a funciones, se tiene que
declarar todas excepto la dimensión de más a la izquierda.
   Por ejemplo, si declaramos un array datos como:
   int datos[4][10][3];
   Entonces una función que reciba el array datos como parámetro
podría declararse como:
   int proceso(int m[ ][10][3]) {
       ...

   }


                                                                              Página 8 de 16
Ingeniería Técnica Industrial
                                                                     Fundamentos de Informática



                                                          Tema 8. Estructuras de Datos Complejas



   Hay tres formas de declarar un parámetro tipo array:
1. Declarando el parámetro como un array indicando su tamaño
2. Declarando el parámetro como un array sin tamaño
3. Declarando el parámetro como un puntero
   int main(void) {                   Ejemplo: Programa que almacena las notas
       float nota[10];                de diez alumnos y muestra por pantalla las
       int i;                         notas de los alumnos que han aprobado.
       for(i =0; i < 10; i++) {
           printf("nDame la nota del alumno nº %d: ", i + 1);
           scanf( "%f", &nota[i] );
       }
       aprobados(nota);
       printf("nPulse una tecla para continuar n");
       getch( );
       return 0;
   }
   La función aprobados() puede implementarse de varias formas:
   /* declarando el parámetro como un array indicando su tamaño */
   void aprobados(float datos[10]) {
   1 int i;
   2 printf("Han aprobado los siguientes alumnos:n");
   3    for (i = 0; i < 10; i++)
   4        if (datos[i] >= 5)
   5        printf("Alumno nº %i: Nota: %5.2f n", i + 1, datos[i] );
   }
   /* declarando el parámetro como un array sin tamaño */
   void aprobados(float datos[ ]) {
   ...
   }
   /* declarando como un puntero, accediendo como si fuera un array */
   void aprobados(float *datos) {
   …
   5        printf("Alumno nº %i: Nota: %5.2f n", i + 1, *(datos + i) );
   }
   El código para estas 3 versiones sería el mismo.

                                                                                  Página 9 de 16
Ingeniería Técnica Industrial
                                                           Fundamentos de Informática



                                                Tema 8. Estructuras de Datos Complejas



8.4 Estructuras
   ¿Podemos almacenar en una sola variable, de los tipos conocidos
hasta ahora, el nombre de un alumno, y su nota media en un curso, p.ej. ?

                                                    Nombre
    NO         Necesitamos algo así: Vble                              Campos de
                                                 Nota_Media           la estructura
    Esta variable es una ESTRUCTURA

   Colección de variables (miembros), que pueden ser de distinto tipo,
que se referencian bajo el mismo nombre y un indentificador de campo.

   Definición de una estructura:
   struct nombre_estructura {
     tipo campo1;                         Antes del main( )
     …                           ¡Ojo! Hemos creado un nuevo tipo de dato
     tipo campoN;            llamado struct nombre_estructura, pero aún
   };                        no hemos declarado ninguna variable de dicho tipo.


   Declaración de una variable del tipo anterior:
   struct nombre_estructura nombre_variable;

   Acceso a un campo miembro de una estructura:
   nombre_variable.nombre_campomiembro;


   Las estructuras:
• Se pueden inicializar igual que los arrays.
• Se pueden copiar y asignar, pasar a funciones como argumento y
  ser devueltas por éstas. Idem con los campos miembros.
• No se pueden comparar. Para saber si dos estructuras son iguales
  hay que comparar uno a uno cada uno de sus miembros.
• Pueden contener como campo miembro otra estructura.
• Sus campos miembros pueden llamarse igual que una variable
  ordinaria o que otro campo miembro de otra estructura distinta.

                                                                      Página 10 de 16
Ingeniería Técnica Industrial
                                                        Fundamentos de Informática



                                            Tema 8. Estructuras de Datos Complejas



   Representar la información de una persona mediante una estructura:
   /* definicion de la estructura direccion */
   struct direccion {
     char calle[30];
     char ciudad[20];
     char provincia[20];
   };
   /* definicion de la estructura datos_per */
   struct datos_per {
     char nombre[35];
     struct direccion dir;
     int edad;
   };
   /* declaracion de variables de tipo datos_per */
   struct datos_per persona1, persona2;


   En este ejemplo, si queremos pedir por teclado la calle y la edad de
persona1 tendríamos que escribir lo siguiente:
   gets(persona1.dir.calle); /* &persona1.dir.calle[0] */
   scanf(“%i”, &persona1.edad);


8.4.1 Arrays de estructuras
   Al igual que podemos declarar arrays de cualquier tipo de datos,
podemos declarar arrays de estructuras. Simplemente debemos definir
primero la estructura y luego declarar una variable array de dicho tipo:
   struct datos_per alumnos[100];

   alumnos 0                  1                   …                      99
    nombre
    calle ciudad prov                             ...
    edad

   Ejemplo:
   Edad del último alumno: alumnos[99].edad;                                        n

   Provincia del primer alumno: alumnos[0].dir.provincia;                          n

                                                                   Página 11 de 16
Ingeniería Técnica Industrial
                                                  Fundamentos de Informática



                                       Tema 8. Estructuras de Datos Complejas


#include <stdio.h>     // printf(), scanf()
#include <stdlib.h>    // system()
#include <conio.h>     // getch()
struct direccion {    /* definicion de la estructura direccion */
  char calle[30];
  char ciudad[20];
};

struct datos_per {   /* definicion de la estructura datos_per */
  char nombre[35];
  struct direccion dir;
  unsigned int edad;
};

int main(void) {
 int n;
 char tecla;
 struct datos_per personas[5];   /* array de tipo datos_per */
 system("cls"); // borra la pantalla
 for (n = 0; n < 5; n++)
 { printf("Nombre: "); gets(personas[n].nombre);
   printf("Calle: "); gets(personas[n].dir.calle);
   printf("Ciudad: "); scanf("%s", personas[n].dir.ciudad);
   printf("Edad: "); scanf("%u", &personas[n].edad);
 }
 do {
   do {
     system("cls");    /* borra la pantalla */
     printf("Dime el nº de la persona a visualizar: ");
     scanf("%i", &n);
   } while (n < 0 || n > 4);
   printf("Nombre: %sn", personas[n].nombre);
   printf("Calle: %sn", personas[n].dir.calle);
   printf("Ciudad: %sn", personas[n].dir.ciudad);
   printf("Edad: %un", &personas[n].edad);
   printf("n¿Desea ver los datos de otra persona (s/n)?");
   tecla = getch();
 } while (tecla == 's');
 return 0;
}

                                                             Página 12 de 16
Ingeniería Técnica Industrial
                                                        Fundamentos de Informática



                                             Tema 8. Estructuras de Datos Complejas



8.4.2 Paso de estructuras a funciones
   C permite pasar estructuras completas a funciones tanto por valor
(por defecto) como por referencia (utilizando &).
    Si la estructura es grande      el paso por valor (copia) del parámetro
struct puede llevar mucho tiempo        En esos casos lo mejor es pasar la
dirección de la estructura (por referencia).
   Si pasamos un array de estructuras a una función, el array se pasa
siempre por referencia (como todos los arrays), con lo que los cambios
efectuados dentro de la función afectan al array original:
   #include <stdio.h>       // printf(), scanf()
   #include <stdlib.h>      // system()
   #include <conio.h>       // getch()

   struct direccion {
     char calle[30];
     char ciudad[20];
   };

   struct datos_per {
     char nombre[35];
     struct direccion dir;
     unsigned int edad;
   };

   int main(void) {
    int n; char tecla;
    struct datos_per personas[5];
    system("cls"); // borra la pantalla
    cargar_datos(personas);
    do {
      do {
        system("cls");
        printf("nº de la persona a ver: ");   scanf("%i", &n);
      } while (n < 0 || n > 4);
      ver_datos(personas[n]);
      printf("n¿Desea ver los datos de otra persona (s/n)?");
      tecla = getch();
    } while (tecla == 's');
    return 0;
   }

                                                                   Página 13 de 16
Ingeniería Técnica Industrial
                                                             Fundamentos de Informática



                                                  Tema 8. Estructuras de Datos Complejas




   void cargar_datos(struct datos_per p[]) {
     int n;
     for (n = 0; n < 5; n++) {
       printf("Nombre: "); scanf("%s", p[n].nombre);
       printf("Calle: "); scanf("%s", p[n].dir.calle);
       printf("Ciudad: "); scanf("%s", p[n].dir.ciudad);
       printf("Edad: "); scanf("%u", &p[n].edad);
     }
   }

   void ver_datos(struct datos_per p) {
     printf("Nombre: %sn", p.nombre);
     printf("Calle: %sn", p.dir.calle);
     printf("Ciudad: %sn", p.dir.ciudad);
     printf("Edad: %un", p.edad);
   }



8.4.3 Paso de elementos de estructuras a funciones
   Además de pasar una estructura completa a una función, podemos
pasar sólo un campo miembro de una estructura.
   Si el campo miembro pasado a la función es:
   • Una variable u otra estructura  se pasa por valor
     Para pasarlo por referencia hay que utilizar el &.
   • Un array       se pasa siempre por referencia
   Las siguientes llamadas sólo pasan un campo miembroro de la estructura:
   funcion1(personas[2].nombre); /* pasa sólo el campo nombre */
   funcion2(personas[2].edad); /* pasa sólo el campo edad */
   funcion3(personas[2].dir); /* pasa sólo el campo dir que es otra estructura*/
   funcion4(personas[2].dir.calle); /* pasa sólo el campo calle */

   Los prototipos de estas funciones serían los siguientes:
   void funcion1(char *cadena);
   void funcion2(int n);
   void funcion3(struct direccion d);
   void funcion4(char cadena[ ]);

                                                                        Página 14 de 16
Ingeniería Técnica Industrial
                                                             Fundamentos de Informática



                                                  Tema 8. Estructuras de Datos Complejas



   Si lo que queremos es pasar un elemento por referencia, debemos
pasar la dirección de dicho elemento:
   funcion1(personas[2].nombre); /* pasa por referencia el campo nombre */
   funcion2(&personas[2].edad); /* pasa por referencia el campo edad */
   funcion3(&personas[2].dir); /*pasa por referencia el campo (estructura) dir*/
   funcion4(personas[2].dir.calle); /* pasa por referencia el campo calle */

   Los prototipos de estas funciones serían los siguientes:
   void funcion1(char *cadena);
   void funcion2(int *n);
   void funcion3(struct direccion *d);
   void funcion4(char cadena[ ]);

    Cuando uno de los elementos de la estructura que pasamos es una
cadena de caracteres, no hace falta utilizar el operador & ya que los
arrays se pasan siempre por referencia y no por valor.


8.4.4 Punteros a estructuras
    De la misma forma que podemos usar punteros a cualquier tipo de
variable, podemos usar punteros a variables de estructuras.
   Para declarar un puntero a una estructura de tipo struct datos_per:
   struct datos_per *p;

    La dirección de una variable de estructura, se obtiene, al igual que
otro tipo de variable, anteponiendo el operador & delante de su nombre:
   struct datos_per persona, *p;
   p = &persona; /* coloca la dir de la estructura persona en p */

   Cuando se usa punteros a estructuras no se debe usar el operador
punto ‘.’ para acceder a un elemento de la estructura a través del
puntero. En su lugar se debe usar el operador ‘->’:
   p->nombre;       /* equivalente a (*p).nombre; */
   p->edad;         /* equivalente a (*p).edad; */
   p->dir.calle; /* equivalente a (*p).dir.calle; */



                                                                        Página 15 de 16
Ingeniería Técnica Industrial
                                                        Fundamentos de Informática



                                             Tema 8. Estructuras de Datos Complejas


   #include <stdio.h>
   #include <conio.h>
   struct direccion { /* definicion estructura direccion */
     char calle[30];
     char ciudad[20];
     char provincia[20];
   };
   struct datos_per { /* definicion estructura datos_per */
     char nombre[35];
     struct direccion dir;
     unsigned int edad;
   };
   void cargar_datos(struct datos_per *p);
   int main(void) {
     int n;
     struct datos_per personas[5];
     for (n = 0; n < 5; n++)
         cargar_datos(&personas[n]);
     printf("Pulse una tecla para terminar"); getch();
     return 0;
   }
   void cargar_datos(struct datos_per *p) {
      printf("Nombre: "); scanf("%s", p->nombre);
      printf("Calle: "); scanf("%s", p->dir.calle);
      printf("Ciudad: "); scanf("%s", p->dir.ciudad);
      printf("Provincia: "); scanf("%s", p->dir.provincia);
      printf("Edad: "); scanf("%u", &p->edad);
   }

8.5 Typedef
   Permite crear un 'alias' de un tipo de C o para uno creado con struct.

   Sintaxis:   typedef tipo_existente alias;

   typedef unsigned char byte;
   byte dato; /* unsigned char dato; */

   Podemos usar typedef para crear alias para estructuras. Por ejemplo:
   typedef struct {                  typedef struct {
     char calle[30];                   char nombre[35];
     char ciudad[20];                  t_direccion dir;
   }t_direccion;                       unsigned int edad;
                                     } t_datos_per;
  t_datos_per personas[5]; /* array de tipo t_datos_per */

                                                                   Página 16 de 16

Mais conteúdo relacionado

Mais procurados

6.1 vectores
6.1 vectores6.1 vectores
6.1 vectoresSNPP
 
Arreglos
ArreglosArreglos
Arregloslichic
 
Ejercicios de matrices y vectores en c++
Ejercicios de matrices y vectores en c++Ejercicios de matrices y vectores en c++
Ejercicios de matrices y vectores en c++Diego Maxdj Chicaiza
 
Arreglos en c ++
Arreglos en c ++Arreglos en c ++
Arreglos en c ++tacubomx
 
Arrays Bidimensionales y Multidimensionales - Carlos Correa
Arrays Bidimensionales y Multidimensionales - Carlos CorreaArrays Bidimensionales y Multidimensionales - Carlos Correa
Arrays Bidimensionales y Multidimensionales - Carlos CorreaCarlitos Correa Jr.
 
Vectores Matrices I
Vectores Matrices IVectores Matrices I
Vectores Matrices Igonmrod
 
Arreglos bidimensionales o matrices
Arreglos bidimensionales o matricesArreglos bidimensionales o matrices
Arreglos bidimensionales o matricesAriannaYadiraT
 
6724640 matrices-java
6724640 matrices-java6724640 matrices-java
6724640 matrices-javabeqa_gothic
 
Referencias MATLAB
Referencias MATLABReferencias MATLAB
Referencias MATLABOmar Sanchez
 
Sistemas numéricos datos y expresiones - tatis
Sistemas numéricos datos y expresiones - tatisSistemas numéricos datos y expresiones - tatis
Sistemas numéricos datos y expresiones - tatisAlcira Ordóñez Rey
 
Arreglos en pseudocodigo 01
Arreglos en pseudocodigo 01Arreglos en pseudocodigo 01
Arreglos en pseudocodigo 01Emerson Garay
 
Clase 10 Estructuras De Datos Y Arreglos
Clase 10 Estructuras De Datos Y ArreglosClase 10 Estructuras De Datos Y Arreglos
Clase 10 Estructuras De Datos Y Arreglossalomonaquino
 
Matlab presentacion enero2012
Matlab presentacion enero2012Matlab presentacion enero2012
Matlab presentacion enero2012gerardoarbito
 

Mais procurados (19)

Arreglos
ArreglosArreglos
Arreglos
 
6.1 vectores
6.1 vectores6.1 vectores
6.1 vectores
 
Arreglos
ArreglosArreglos
Arreglos
 
Ejercicios de matrices y vectores en c++
Ejercicios de matrices y vectores en c++Ejercicios de matrices y vectores en c++
Ejercicios de matrices y vectores en c++
 
Arreglos unidimensionales
Arreglos unidimensionalesArreglos unidimensionales
Arreglos unidimensionales
 
Arreglos en C
Arreglos en CArreglos en C
Arreglos en C
 
Arreglos en c ++
Arreglos en c ++Arreglos en c ++
Arreglos en c ++
 
Arrays Bidimensionales y Multidimensionales - Carlos Correa
Arrays Bidimensionales y Multidimensionales - Carlos CorreaArrays Bidimensionales y Multidimensionales - Carlos Correa
Arrays Bidimensionales y Multidimensionales - Carlos Correa
 
Informatica
InformaticaInformatica
Informatica
 
Vectores Matrices I
Vectores Matrices IVectores Matrices I
Vectores Matrices I
 
arreglos y matrices
arreglos  y matricesarreglos  y matrices
arreglos y matrices
 
Arreglos-Programacion
Arreglos-ProgramacionArreglos-Programacion
Arreglos-Programacion
 
Arreglos bidimensionales o matrices
Arreglos bidimensionales o matricesArreglos bidimensionales o matrices
Arreglos bidimensionales o matrices
 
6724640 matrices-java
6724640 matrices-java6724640 matrices-java
6724640 matrices-java
 
Referencias MATLAB
Referencias MATLABReferencias MATLAB
Referencias MATLAB
 
Sistemas numéricos datos y expresiones - tatis
Sistemas numéricos datos y expresiones - tatisSistemas numéricos datos y expresiones - tatis
Sistemas numéricos datos y expresiones - tatis
 
Arreglos en pseudocodigo 01
Arreglos en pseudocodigo 01Arreglos en pseudocodigo 01
Arreglos en pseudocodigo 01
 
Clase 10 Estructuras De Datos Y Arreglos
Clase 10 Estructuras De Datos Y ArreglosClase 10 Estructuras De Datos Y Arreglos
Clase 10 Estructuras De Datos Y Arreglos
 
Matlab presentacion enero2012
Matlab presentacion enero2012Matlab presentacion enero2012
Matlab presentacion enero2012
 

Destaque

03 -fundamentos_de_la_tecnologia_orientada_a_objetos
03  -fundamentos_de_la_tecnologia_orientada_a_objetos03  -fundamentos_de_la_tecnologia_orientada_a_objetos
03 -fundamentos_de_la_tecnologia_orientada_a_objetoskarlalopezbello
 
02 -introduccion_a_la_tecnologia_orientada_a_objetos
02  -introduccion_a_la_tecnologia_orientada_a_objetos02  -introduccion_a_la_tecnologia_orientada_a_objetos
02 -introduccion_a_la_tecnologia_orientada_a_objetoskarlalopezbello
 
Programacion ii modulo2-leccion1
Programacion ii modulo2-leccion1Programacion ii modulo2-leccion1
Programacion ii modulo2-leccion1karlalopezbello
 
Programacion ii modulo3-leccion1
Programacion ii modulo3-leccion1Programacion ii modulo3-leccion1
Programacion ii modulo3-leccion1karlalopezbello
 
Programacion ii modulo3-leccion2
Programacion ii modulo3-leccion2Programacion ii modulo3-leccion2
Programacion ii modulo3-leccion2karlalopezbello
 
Programacion ii modulo1-leccion1-
Programacion ii modulo1-leccion1-Programacion ii modulo1-leccion1-
Programacion ii modulo1-leccion1-karlalopezbello
 
Programacion ii modulo2-leccion2
Programacion ii modulo2-leccion2Programacion ii modulo2-leccion2
Programacion ii modulo2-leccion2karlalopezbello
 
Programacion ii modulo2-leccion3
Programacion ii modulo2-leccion3Programacion ii modulo2-leccion3
Programacion ii modulo2-leccion3karlalopezbello
 

Destaque (10)

03 -fundamentos_de_la_tecnologia_orientada_a_objetos
03  -fundamentos_de_la_tecnologia_orientada_a_objetos03  -fundamentos_de_la_tecnologia_orientada_a_objetos
03 -fundamentos_de_la_tecnologia_orientada_a_objetos
 
02 -introduccion_a_la_tecnologia_orientada_a_objetos
02  -introduccion_a_la_tecnologia_orientada_a_objetos02  -introduccion_a_la_tecnologia_orientada_a_objetos
02 -introduccion_a_la_tecnologia_orientada_a_objetos
 
Programacion ii modulo2-leccion1
Programacion ii modulo2-leccion1Programacion ii modulo2-leccion1
Programacion ii modulo2-leccion1
 
Programacion ii modulo3-leccion1
Programacion ii modulo3-leccion1Programacion ii modulo3-leccion1
Programacion ii modulo3-leccion1
 
Programacion ii modulo3-leccion2
Programacion ii modulo3-leccion2Programacion ii modulo3-leccion2
Programacion ii modulo3-leccion2
 
Programacion ii modulo1-leccion1-
Programacion ii modulo1-leccion1-Programacion ii modulo1-leccion1-
Programacion ii modulo1-leccion1-
 
Programacion ii modulo2-leccion2
Programacion ii modulo2-leccion2Programacion ii modulo2-leccion2
Programacion ii modulo2-leccion2
 
Didactica del chat
Didactica del chatDidactica del chat
Didactica del chat
 
Programacion ii modulo2-leccion3
Programacion ii modulo2-leccion3Programacion ii modulo2-leccion3
Programacion ii modulo2-leccion3
 
Estructuras punteros
Estructuras punterosEstructuras punteros
Estructuras punteros
 

Semelhante a Transparencias8

3 desarollo manejo datos capitulo 2 -01 arreglos dos dimensiones (2)
3 desarollo manejo datos capitulo 2 -01 arreglos dos dimensiones (2)3 desarollo manejo datos capitulo 2 -01 arreglos dos dimensiones (2)
3 desarollo manejo datos capitulo 2 -01 arreglos dos dimensiones (2)luis freddy
 
3 desarollo manejo datos capitulo 2 -01 arreglos dos dimensiones (5)
3 desarollo manejo datos capitulo 2 -01 arreglos dos dimensiones (5)3 desarollo manejo datos capitulo 2 -01 arreglos dos dimensiones (5)
3 desarollo manejo datos capitulo 2 -01 arreglos dos dimensiones (5)luis freddy
 
3 desarollo manejo datos capitulo 1 -01 arreglos de dimension (6)
3 desarollo manejo datos capitulo 1 -01 arreglos de dimension (6)3 desarollo manejo datos capitulo 1 -01 arreglos de dimension (6)
3 desarollo manejo datos capitulo 1 -01 arreglos de dimension (6)luis freddy
 
Unidad 7 Arreglos.pdf
Unidad 7 Arreglos.pdfUnidad 7 Arreglos.pdf
Unidad 7 Arreglos.pdfLuisSierraPea
 
Funciones con vectores y matrices
Funciones con vectores y matricesFunciones con vectores y matrices
Funciones con vectores y matricesJohanna Marin
 
Funciones con vectores y matrices
Funciones con vectores y matricesFunciones con vectores y matrices
Funciones con vectores y matricesJohanna Marin
 
Utp pti_s5_arreglos
 Utp pti_s5_arreglos Utp pti_s5_arreglos
Utp pti_s5_arreglosjcbenitezp
 
Utp pti_s5_arreglos 2012-2
 Utp pti_s5_arreglos 2012-2 Utp pti_s5_arreglos 2012-2
Utp pti_s5_arreglos 2012-2jcbenitezp
 
Pres arreglosmat animacion
Pres arreglosmat animacionPres arreglosmat animacion
Pres arreglosmat animacionJLAntonio
 
Fundamentos de Programacion - Unidad 5 arreglos (vectores)
Fundamentos de Programacion - Unidad 5 arreglos (vectores)Fundamentos de Programacion - Unidad 5 arreglos (vectores)
Fundamentos de Programacion - Unidad 5 arreglos (vectores)José Antonio Sandoval Acosta
 
Tutorial de matrices c#
Tutorial de matrices c#Tutorial de matrices c#
Tutorial de matrices c#elidetjc
 

Semelhante a Transparencias8 (20)

Tema 5 - Estructuras de datos.pdf
Tema 5 - Estructuras de datos.pdfTema 5 - Estructuras de datos.pdf
Tema 5 - Estructuras de datos.pdf
 
arrays
arraysarrays
arrays
 
3 desarollo manejo datos capitulo 2 -01 arreglos dos dimensiones (2)
3 desarollo manejo datos capitulo 2 -01 arreglos dos dimensiones (2)3 desarollo manejo datos capitulo 2 -01 arreglos dos dimensiones (2)
3 desarollo manejo datos capitulo 2 -01 arreglos dos dimensiones (2)
 
3 desarollo manejo datos capitulo 2 -01 arreglos dos dimensiones (5)
3 desarollo manejo datos capitulo 2 -01 arreglos dos dimensiones (5)3 desarollo manejo datos capitulo 2 -01 arreglos dos dimensiones (5)
3 desarollo manejo datos capitulo 2 -01 arreglos dos dimensiones (5)
 
3 desarollo manejo datos capitulo 1 -01 arreglos de dimension (6)
3 desarollo manejo datos capitulo 1 -01 arreglos de dimension (6)3 desarollo manejo datos capitulo 1 -01 arreglos de dimension (6)
3 desarollo manejo datos capitulo 1 -01 arreglos de dimension (6)
 
Java 1
Java 1Java 1
Java 1
 
Estructuras
Estructuras Estructuras
Estructuras
 
Unidad 7 Arreglos.pdf
Unidad 7 Arreglos.pdfUnidad 7 Arreglos.pdf
Unidad 7 Arreglos.pdf
 
Funciones con vectores y matrices
Funciones con vectores y matricesFunciones con vectores y matrices
Funciones con vectores y matrices
 
Funciones con vectores y matrices
Funciones con vectores y matricesFunciones con vectores y matrices
Funciones con vectores y matrices
 
Programación 1: arreglos en C
Programación 1: arreglos en CProgramación 1: arreglos en C
Programación 1: arreglos en C
 
Arreglos y matrices
Arreglos y matricesArreglos y matrices
Arreglos y matrices
 
Arreglos
ArreglosArreglos
Arreglos
 
Utp pti_s5_arreglos
 Utp pti_s5_arreglos Utp pti_s5_arreglos
Utp pti_s5_arreglos
 
Utp pti_s5_arreglos 2012-2
 Utp pti_s5_arreglos 2012-2 Utp pti_s5_arreglos 2012-2
Utp pti_s5_arreglos 2012-2
 
Pres arreglosmat animacion
Pres arreglosmat animacionPres arreglosmat animacion
Pres arreglosmat animacion
 
Fundamentos de Programacion - Unidad 5 arreglos (vectores)
Fundamentos de Programacion - Unidad 5 arreglos (vectores)Fundamentos de Programacion - Unidad 5 arreglos (vectores)
Fundamentos de Programacion - Unidad 5 arreglos (vectores)
 
11 arreglos-multidimensionales
11 arreglos-multidimensionales11 arreglos-multidimensionales
11 arreglos-multidimensionales
 
Tutorial de matrices c#
Tutorial de matrices c#Tutorial de matrices c#
Tutorial de matrices c#
 
Tutorial de matrices c#
Tutorial de matrices c#Tutorial de matrices c#
Tutorial de matrices c#
 

Mais de karlalopezbello (20)

Didactica del foro
Didactica del foroDidactica del foro
Didactica del foro
 
Guia completa de_moodle
Guia completa de_moodleGuia completa de_moodle
Guia completa de_moodle
 
Publicacion de material
Publicacion de materialPublicacion de material
Publicacion de material
 
Sistemas de comunicacion
Sistemas de comunicacionSistemas de comunicacion
Sistemas de comunicacion
 
Actividades en moodle
Actividades en moodleActividades en moodle
Actividades en moodle
 
Plataforma moodle
Plataforma moodlePlataforma moodle
Plataforma moodle
 
Introduccion unegvirtual
Introduccion unegvirtualIntroduccion unegvirtual
Introduccion unegvirtual
 
Guia para montar_el_aula_1_
Guia para montar_el_aula_1_Guia para montar_el_aula_1_
Guia para montar_el_aula_1_
 
Configuracion del perfil
Configuracion del perfilConfiguracion del perfil
Configuracion del perfil
 
Configuracion del perfil
Configuracion del perfilConfiguracion del perfil
Configuracion del perfil
 
Transparencias7
Transparencias7Transparencias7
Transparencias7
 
Transparencias5
Transparencias5Transparencias5
Transparencias5
 
Transparencias4
Transparencias4Transparencias4
Transparencias4
 
Transparencias3
Transparencias3Transparencias3
Transparencias3
 
algoritmica
algoritmicaalgoritmica
algoritmica
 
Estructuras lineales
Estructuras linealesEstructuras lineales
Estructuras lineales
 
Estructuras no-lineales
Estructuras no-linealesEstructuras no-lineales
Estructuras no-lineales
 
Manejo archivos
Manejo archivosManejo archivos
Manejo archivos
 
Ordenacion
OrdenacionOrdenacion
Ordenacion
 
Recursion
RecursionRecursion
Recursion
 

Transparencias8

  • 1. Ingeniería Técnica Industrial Fundamentos de Informática Tema 8. Estructuras de Datos Complejas TEMA 8. Estructuras de Datos Complejas 8.1 Vectores Estáticos Con las variables que conocemos hasta ahora, ¿ES POSIBLE almacenar la nota de todos los alumnos en UNA SOLA VARIABLE ? NO Necesitamos algo así: Vble 5.6 7 3.9 ... 6.2 Esta variable es un vector estático o array colección de variables del mismo tipo que están almacenados en posiciones contiguas de memoria y que se referencian utilizando un nombre (que es común para todos los datos) y un índice (que indica la posición del dato dentro de todo el conjunto). La dirección más baja corresponde al primer elemento y la más alta al último. Ejemplo: Notas 5.6 7 3.9 ... 6.2 Indice 0 1 2 Max-1 de modo que la nota del 3er alumno es: Notas[2] Página 1 de 16
  • 2. Ingeniería Técnica Industrial Fundamentos de Informática Tema 8. Estructuras de Datos Complejas 8.1.1 Vectores o Arrays unidimensionales Gráficamente: Vble 5 7 3 ... 6 Indice 0 1 2 tamaño-1 El formato general para declarar un array unidimensional es tipo nombre[tamaño]; Al declarar el array, se indica entre corchetes el número de elementos que como máximo va a tener. Estos elementos serán del tipo indicado. Ejemplo: 1. Declarar una variable capaz de almacenar las notas de 50 alumnos: float NOTAS[50]; 2. Suponiendo el vector relleno, mostrar las notas de todos los alumnos: ¿ Podría ser i <= 50 ? for (i = 0; i < 50; i++) printf(“La nota del alumno %i es %.2f n”, i+1, NOTAS[i]); ¿ Por qué? 3. ¿Cuál es la nota media de la clase? float MEDIA, TOTAL = 0; for (i = 0; i < 50; i++) TOTAL = TOTAL + NOTAS[i]; MEDIA = TOTAL / 50; Con respecto a los arrays debemos tener en cuenta lo siguiente: • En C todos los arrays usan 0 como índice del primer elemento. • El C permite indexar un array por encima del nº de elementos que contiene no indica ningún mensaje de error en la compilación. int main(void){ int edad[20], i; for (i = 1; i <= 20; i++) { /* OJO aquí hay un fallo */ printf(“Dame la edad de la persona nº %i n”, i); scanf(“%i”, &edad[i]); } 1. Error1: El índice del elemento 1º es el 0 (no el 1). } 2. Error2: El último elemento es edad[19] (no edad[20]). Al compilar no da error pero durante la ejecución, la ultima edad se introduce en la zona de memoria siguiente a la tabla, donde puede que haya alguna variable o parte del código binario del programa. Página 2 de 16
  • 3. Ingeniería Técnica Industrial Fundamentos de Informática Tema 8. Estructuras de Datos Complejas 8.1.2 Vectores o Arrays multidimensionales El formato general de una declaración de array multidimensional es: tipo nombre[tamaño1][tamaño2]…[tamañoN]; El más usado es el array bidimensional o matriz (vector de vectores). Ej: Almacenar la temperatura media de cada mes, durante 5 años (de 2001 a 2005): años meses float TEMP_MEDIA[5][12]; Mostrar la temperatura media de cada mes, para todos los años: for (int agno = 0; agno < 5; agno++) Fijamos el año { printf(“En %i, las temperaturas fueron: n”, 2001 + agno); for (mes = 0; mes < 12; mes++) Nos movemos por printf(“En el mes %i, %.2f grados n”, mes + 1, TEMP_MEDIA[agno][mes]); los meses de ese año } En los arrays bidimensionales el indice 1º indica la fila y el 2º la columna Ejemplo: almacenar en un array de 10 x 10 la tabla de multiplicar int main(void) { int i, j, tabla[10][10]; for (i = 0; i < 10; i++) { for (j = 0; j < 10; j++) tabla[i][j] = (i + 1) * (j + 1); } } Ej: Almacenar la temperatura media de cada día, de cada mes, para 5 años (de 2001 a 2005): años meses días float TEMPERATURA[5][12][30]; Mostrar la temperatura media de cada mes y año, para todos los años: float media_mes, media_agno; for (int agno = 0; agno < 5; agno++) Fijamos el año { media_agno = 0; printf(“En %i, las temperaturas fueron: n”, 2001 + agno); for (mes = 0; mes < 12; mes++) Nos movemos por los meses de ese año { media_mes = 0; Recorremos los 30 días de for (dia = 0; dia < 30; dia++) ese mes y ese año media_mes = media_mes + TEMPERATURA[agno][mes][dia]; media_mes = media_mes / 30; printf(“En el mes %i, %.2f grados n”, mes + 1, media_mes); media_agno = media_agno + media_mes; } media_agno = media_agno / 12; printf(“En %i, la media fue %.2f n”, 2001 + agno, media_agno); } Página 3 de 16
  • 4. Ingeniería Técnica Industrial Fundamentos de Informática Tema 8. Estructuras de Datos Complejas 8.1.3 Inicialización de arrays (indicando y sin indicar el tamaño) El formato general de una inicialización de un array es el siguiente: tipo nombre[tamaño1]…[tamañoN] = { valor1, valor2, ..., valorN }; C permite la inicialización de los arrays globales y los locales static: int i[5] = { 0, 1, 4, 9, 16 }; int i[] = { 0, 1, 4, 9, 16 }; /* sin indicar el tamaño */ Si no se indica el tamaño, se crea un array tan grande como para albergar todos los datos indicados (es más cómodo). Las declaraciones anteriores son equivalentes a esta otra: int i[5]; i[0] = 0; i[1] = 1; i[2] = 4; i[3] = 9; i[4] = 16; Los arrays multidimensionales se inicializan de la misma manera (se deben indicar todas las dimensiones excepto la de más a la izquierda): Indicando el tamaño Sin indicar el tamaño int datos[3][2] = {1,1, 2,4, 3,9}; int datos[][2] = {1,1, 2,4, 3,9}; int datos[3][2] = { 1, 1, int datos[][2] = { 1, 1 2, 4, 2, 4, 3, 9 }; 3, 9 }; int datos[3][2]; datos[0][0] = 1; datos[0][1] = 1; datos[1][0] = 2; datos[1][1] = 4; datos[2][0] = 3; datos[2][1] = 9; Página 4 de 16
  • 5. Ingeniería Técnica Industrial Fundamentos de Informática Tema 8. Estructuras de Datos Complejas 8.2 Cadenas o vector de caracteres Una cadena o vector de caracteres (strings) es un vector que contiene en cada celda un carácter del código ASCII. En C una cadena se implementa mediante un vector de caracteres terminado en un nulo (‘0’) que indica el final de la cadena Hay que contar con él, a la hora de pensar en el tamaño del vector. char cadena[11]; /* puede guardar una cadena de 10 caracteres */ Aunque C no tiene un tipo de datos string, sí que permite constantes de cadenas. Una constante de cadena es una lista de caracteres encerrada entre comillas dobles (“). “Bienvenidos” “Pulsa una tecla para continuar” No se necesita añadir el nulo ('0') manualmente en el final de las constantes de cadenas, el compilador hace esto automáticamente. 8.2.1 Inicialización de cadenas Los arrays de caracteres permiten una inicialización abreviada: char nombre[tamaño] = “cadena”; El compilador automáticamente añade el terminador nulo: char saludo[5] = “hola”; char saludo[] = “hola”; // sin indicar el tamaño char saludo[5] = { ‘h’, ‘o’, ‘l’, ‘a’, ‘0’ }; // mas incómodo Consideraciones a tener en cuenta al trabajar con cadenas: 1. No se pueden asignar cadenas con el operador = usar strcpy() 2. No se pueden comparar cadenas con el operador == usar strcmp() 3. No se puede asignar a una cadena un valor con el operador = salvo en la declaración de la misma. 4. Para leer desde teclado cadenas que contengan espacios en blanco usaremos la función gets( ) ya que scanf( ) no lee espacios. Página 5 de 16
  • 6. Ingeniería Técnica Industrial Fundamentos de Informática Tema 8. Estructuras de Datos Complejas Para trabajar con cadenas, C dispone de la librería string.h: Prototipo de función Acción: char *strcpy(char *c1, const char *c2) Copia la cadena c2 sobre la cadena c1. char *strcat(char *c1,const char *c2) Concatena la cadena c1 con la cadena c2 char *strchr(const char *c1, int ch1) Busca el carácter ch1 en la cadena c1. Devuelve un puntero a la 1ª ocurrencia de ch1 en c1. Si no lo encuentra devuelve NULL. int strcmp(const char *c1, const char *c2) Compara la cadena c1 con la cadena c2. Devuelve un < 0 si c1 < c2; un > 0 si c1 > c2 y 0 si c1 es igual a c2. int strlen(const char *c1) Devuelve la longitud de la cadena c1 sin contar el terminador nulo ('0'). char *strupr(char *c1) Convierte la cadena c1 a mayúsculas. char *strlwr(char *c1) Convierte la cadena c1 a minúsculas char *strset(char *c1,int ch1) Rellena toda la cadena c1 con el carácter ch1 char *strstr(const char*c1, const char *c2) Encuentra la 1ª coincidencia de la subcadena c2 dentro de c1. Da NULL si no la encuentra. Ejemplo: #include <stdio.h> // printf(), scanf() #include <conio.h> // getch() #include <string.h> // strcpy(), strcmp(), strcat(), strlen() int main(void) { char nombre[30], cadena[80]; printf(“Dime tu nombre:”); gets(nombre); /* scanf(“%s”,…) no lee espacios en blanco */ strcpy(cadena, nombre); if (strcmp(nombre, cadena) == 0) printf(“Las cadenas son iguales”); printf(“mi nombre es %s n”, nombre); strcat(cadena,” es listo”); // concatena 'es listo' a cadena printf(“%s”, cadena); printf(“La frase tiene %i caracteres n”, strlen(cadena)); strcpy(nombre, ””); // nombre[0] = '0' (borra la cadena) getch(); return 0; } Página 6 de 16
  • 7. Ingeniería Técnica Industrial Fundamentos de Informática Tema 8. Estructuras de Datos Complejas Para crear un array de cadenas, se usa una matriz de caracteres, en la que el tamaño del índice izquierdo determina el número de cadenas a almacenar y el tamaño del derecho especifica la longitud máxima de las cadenas a guardar. int main(void) { int i; char direcciones[10][50]; for (i = 0; i < 10; i++) { printf(“Introduce la dirección nº %i:”, i + 1); scanf(“%s”, direcciones[i]); } for (i = 0; i < 10; i++) printf("La dirección nº %i es: %sn", i + 1, direcciones[i]); getch(); return 0; } No hace falta poner el & en el scanf ya que las sentencias: scanf(“%s”, direcciones[i]); scanf(“%s”, &direcciones[i][0]); son equivalentes: devuelven un puntero al elto 1º del array de índice i. En C, el nombre de un array es un puntero al primer elemento del array. En los de 2 dimensiones, al indicar sólo el primer índice, es un puntero al primer elemento de dicho índice. int main(void){ Programa que lee 20 líneas int i, vocal[5] = {0, 0, 0, 0, 0}; de texto (de 80 caracteres) char frase[20][81], vocales[]=”aeiou”; por teclado y visualiza por for(i = 0; i < 20; i++){ pantalla aquellas líneas que empiezan por vocal, y un printf(“Introduzca frase nº %d: “, i); resumen indicando el nº de gets(frase[i]); // gets(&frase[i][0]) líneas que empiezan por } cada vocal for(i = 0; i < 20; i++){ switch ( toupper(frase[i][0]) ) { case ‘A’: vocal[0]++; printf(“%sn”, frase[i]); break; case ‘E’: vocal[1]++; printf(“%sn”, frase[i]); break; case ‘I’: vocal[2]++; printf(“%sn”, frase[i]); break; case ‘O’: vocal[3]++; printf(“%sn”, frase[i]); break; case ‘U’: vocal[4]++; printf(“%sn”, frase[i]); } } for (i = 0; i < 5; i++) printf(“%i frases empiezan por %c n”, vocal[i], vocales[i]); return 0; } Página 7 de 16
  • 8. Ingeniería Técnica Industrial Fundamentos de Informática Tema 8. Estructuras de Datos Complejas 8.3 Paso de cadenas y arrays a funciones Para pasar un array completo como argumento a una función, en la llamada a la función sólo se pone el nombre del array (sin índice ni [ ]). Si queremos pasar un único elemento a una función, se pondrá el nombre y entre corchetes el indice (nombre_array[índice_elemento]). Los arrays se pasan siempre por referencia a una función: todos los cambios realizados a la tabla en la función afectan a la tabla original: void ver(char c[20], int tope); void ver(char c[20], int tope) void cambia(char c[20], int salto); { int i; int main(void) { for(i =0; i < tope; i++) char letras[20]; printf("%c", c[i]); int i, j =10; printf("n"); for (i = 0; i < 20; i++) } letras[i] ='a' + i; ver(letras, j); void cambia(char c[20], int salto) cambia(letras, 5); { int i; ver(letras, j); for(i = 0; i < 20; i++) return 0; c[i] = c[i] + salto; } } Al ejecutar el programa, el resultado mostrado es el siguiente: abcdefghij fghijklmno Para pasar arrays multidimensionales a funciones, se tiene que declarar todas excepto la dimensión de más a la izquierda. Por ejemplo, si declaramos un array datos como: int datos[4][10][3]; Entonces una función que reciba el array datos como parámetro podría declararse como: int proceso(int m[ ][10][3]) { ... } Página 8 de 16
  • 9. Ingeniería Técnica Industrial Fundamentos de Informática Tema 8. Estructuras de Datos Complejas Hay tres formas de declarar un parámetro tipo array: 1. Declarando el parámetro como un array indicando su tamaño 2. Declarando el parámetro como un array sin tamaño 3. Declarando el parámetro como un puntero int main(void) { Ejemplo: Programa que almacena las notas float nota[10]; de diez alumnos y muestra por pantalla las int i; notas de los alumnos que han aprobado. for(i =0; i < 10; i++) { printf("nDame la nota del alumno nº %d: ", i + 1); scanf( "%f", &nota[i] ); } aprobados(nota); printf("nPulse una tecla para continuar n"); getch( ); return 0; } La función aprobados() puede implementarse de varias formas: /* declarando el parámetro como un array indicando su tamaño */ void aprobados(float datos[10]) { 1 int i; 2 printf("Han aprobado los siguientes alumnos:n"); 3 for (i = 0; i < 10; i++) 4 if (datos[i] >= 5) 5 printf("Alumno nº %i: Nota: %5.2f n", i + 1, datos[i] ); } /* declarando el parámetro como un array sin tamaño */ void aprobados(float datos[ ]) { ... } /* declarando como un puntero, accediendo como si fuera un array */ void aprobados(float *datos) { … 5 printf("Alumno nº %i: Nota: %5.2f n", i + 1, *(datos + i) ); } El código para estas 3 versiones sería el mismo. Página 9 de 16
  • 10. Ingeniería Técnica Industrial Fundamentos de Informática Tema 8. Estructuras de Datos Complejas 8.4 Estructuras ¿Podemos almacenar en una sola variable, de los tipos conocidos hasta ahora, el nombre de un alumno, y su nota media en un curso, p.ej. ? Nombre NO Necesitamos algo así: Vble Campos de Nota_Media la estructura Esta variable es una ESTRUCTURA Colección de variables (miembros), que pueden ser de distinto tipo, que se referencian bajo el mismo nombre y un indentificador de campo. Definición de una estructura: struct nombre_estructura { tipo campo1; Antes del main( ) … ¡Ojo! Hemos creado un nuevo tipo de dato tipo campoN; llamado struct nombre_estructura, pero aún }; no hemos declarado ninguna variable de dicho tipo. Declaración de una variable del tipo anterior: struct nombre_estructura nombre_variable; Acceso a un campo miembro de una estructura: nombre_variable.nombre_campomiembro; Las estructuras: • Se pueden inicializar igual que los arrays. • Se pueden copiar y asignar, pasar a funciones como argumento y ser devueltas por éstas. Idem con los campos miembros. • No se pueden comparar. Para saber si dos estructuras son iguales hay que comparar uno a uno cada uno de sus miembros. • Pueden contener como campo miembro otra estructura. • Sus campos miembros pueden llamarse igual que una variable ordinaria o que otro campo miembro de otra estructura distinta. Página 10 de 16
  • 11. Ingeniería Técnica Industrial Fundamentos de Informática Tema 8. Estructuras de Datos Complejas Representar la información de una persona mediante una estructura: /* definicion de la estructura direccion */ struct direccion { char calle[30]; char ciudad[20]; char provincia[20]; }; /* definicion de la estructura datos_per */ struct datos_per { char nombre[35]; struct direccion dir; int edad; }; /* declaracion de variables de tipo datos_per */ struct datos_per persona1, persona2; En este ejemplo, si queremos pedir por teclado la calle y la edad de persona1 tendríamos que escribir lo siguiente: gets(persona1.dir.calle); /* &persona1.dir.calle[0] */ scanf(“%i”, &persona1.edad); 8.4.1 Arrays de estructuras Al igual que podemos declarar arrays de cualquier tipo de datos, podemos declarar arrays de estructuras. Simplemente debemos definir primero la estructura y luego declarar una variable array de dicho tipo: struct datos_per alumnos[100]; alumnos 0 1 … 99 nombre calle ciudad prov ... edad Ejemplo: Edad del último alumno: alumnos[99].edad; n Provincia del primer alumno: alumnos[0].dir.provincia; n Página 11 de 16
  • 12. Ingeniería Técnica Industrial Fundamentos de Informática Tema 8. Estructuras de Datos Complejas #include <stdio.h> // printf(), scanf() #include <stdlib.h> // system() #include <conio.h> // getch() struct direccion { /* definicion de la estructura direccion */ char calle[30]; char ciudad[20]; }; struct datos_per { /* definicion de la estructura datos_per */ char nombre[35]; struct direccion dir; unsigned int edad; }; int main(void) { int n; char tecla; struct datos_per personas[5]; /* array de tipo datos_per */ system("cls"); // borra la pantalla for (n = 0; n < 5; n++) { printf("Nombre: "); gets(personas[n].nombre); printf("Calle: "); gets(personas[n].dir.calle); printf("Ciudad: "); scanf("%s", personas[n].dir.ciudad); printf("Edad: "); scanf("%u", &personas[n].edad); } do { do { system("cls"); /* borra la pantalla */ printf("Dime el nº de la persona a visualizar: "); scanf("%i", &n); } while (n < 0 || n > 4); printf("Nombre: %sn", personas[n].nombre); printf("Calle: %sn", personas[n].dir.calle); printf("Ciudad: %sn", personas[n].dir.ciudad); printf("Edad: %un", &personas[n].edad); printf("n¿Desea ver los datos de otra persona (s/n)?"); tecla = getch(); } while (tecla == 's'); return 0; } Página 12 de 16
  • 13. Ingeniería Técnica Industrial Fundamentos de Informática Tema 8. Estructuras de Datos Complejas 8.4.2 Paso de estructuras a funciones C permite pasar estructuras completas a funciones tanto por valor (por defecto) como por referencia (utilizando &). Si la estructura es grande el paso por valor (copia) del parámetro struct puede llevar mucho tiempo En esos casos lo mejor es pasar la dirección de la estructura (por referencia). Si pasamos un array de estructuras a una función, el array se pasa siempre por referencia (como todos los arrays), con lo que los cambios efectuados dentro de la función afectan al array original: #include <stdio.h> // printf(), scanf() #include <stdlib.h> // system() #include <conio.h> // getch() struct direccion { char calle[30]; char ciudad[20]; }; struct datos_per { char nombre[35]; struct direccion dir; unsigned int edad; }; int main(void) { int n; char tecla; struct datos_per personas[5]; system("cls"); // borra la pantalla cargar_datos(personas); do { do { system("cls"); printf("nº de la persona a ver: "); scanf("%i", &n); } while (n < 0 || n > 4); ver_datos(personas[n]); printf("n¿Desea ver los datos de otra persona (s/n)?"); tecla = getch(); } while (tecla == 's'); return 0; } Página 13 de 16
  • 14. Ingeniería Técnica Industrial Fundamentos de Informática Tema 8. Estructuras de Datos Complejas void cargar_datos(struct datos_per p[]) { int n; for (n = 0; n < 5; n++) { printf("Nombre: "); scanf("%s", p[n].nombre); printf("Calle: "); scanf("%s", p[n].dir.calle); printf("Ciudad: "); scanf("%s", p[n].dir.ciudad); printf("Edad: "); scanf("%u", &p[n].edad); } } void ver_datos(struct datos_per p) { printf("Nombre: %sn", p.nombre); printf("Calle: %sn", p.dir.calle); printf("Ciudad: %sn", p.dir.ciudad); printf("Edad: %un", p.edad); } 8.4.3 Paso de elementos de estructuras a funciones Además de pasar una estructura completa a una función, podemos pasar sólo un campo miembro de una estructura. Si el campo miembro pasado a la función es: • Una variable u otra estructura se pasa por valor Para pasarlo por referencia hay que utilizar el &. • Un array se pasa siempre por referencia Las siguientes llamadas sólo pasan un campo miembroro de la estructura: funcion1(personas[2].nombre); /* pasa sólo el campo nombre */ funcion2(personas[2].edad); /* pasa sólo el campo edad */ funcion3(personas[2].dir); /* pasa sólo el campo dir que es otra estructura*/ funcion4(personas[2].dir.calle); /* pasa sólo el campo calle */ Los prototipos de estas funciones serían los siguientes: void funcion1(char *cadena); void funcion2(int n); void funcion3(struct direccion d); void funcion4(char cadena[ ]); Página 14 de 16
  • 15. Ingeniería Técnica Industrial Fundamentos de Informática Tema 8. Estructuras de Datos Complejas Si lo que queremos es pasar un elemento por referencia, debemos pasar la dirección de dicho elemento: funcion1(personas[2].nombre); /* pasa por referencia el campo nombre */ funcion2(&personas[2].edad); /* pasa por referencia el campo edad */ funcion3(&personas[2].dir); /*pasa por referencia el campo (estructura) dir*/ funcion4(personas[2].dir.calle); /* pasa por referencia el campo calle */ Los prototipos de estas funciones serían los siguientes: void funcion1(char *cadena); void funcion2(int *n); void funcion3(struct direccion *d); void funcion4(char cadena[ ]); Cuando uno de los elementos de la estructura que pasamos es una cadena de caracteres, no hace falta utilizar el operador & ya que los arrays se pasan siempre por referencia y no por valor. 8.4.4 Punteros a estructuras De la misma forma que podemos usar punteros a cualquier tipo de variable, podemos usar punteros a variables de estructuras. Para declarar un puntero a una estructura de tipo struct datos_per: struct datos_per *p; La dirección de una variable de estructura, se obtiene, al igual que otro tipo de variable, anteponiendo el operador & delante de su nombre: struct datos_per persona, *p; p = &persona; /* coloca la dir de la estructura persona en p */ Cuando se usa punteros a estructuras no se debe usar el operador punto ‘.’ para acceder a un elemento de la estructura a través del puntero. En su lugar se debe usar el operador ‘->’: p->nombre; /* equivalente a (*p).nombre; */ p->edad; /* equivalente a (*p).edad; */ p->dir.calle; /* equivalente a (*p).dir.calle; */ Página 15 de 16
  • 16. Ingeniería Técnica Industrial Fundamentos de Informática Tema 8. Estructuras de Datos Complejas #include <stdio.h> #include <conio.h> struct direccion { /* definicion estructura direccion */ char calle[30]; char ciudad[20]; char provincia[20]; }; struct datos_per { /* definicion estructura datos_per */ char nombre[35]; struct direccion dir; unsigned int edad; }; void cargar_datos(struct datos_per *p); int main(void) { int n; struct datos_per personas[5]; for (n = 0; n < 5; n++) cargar_datos(&personas[n]); printf("Pulse una tecla para terminar"); getch(); return 0; } void cargar_datos(struct datos_per *p) { printf("Nombre: "); scanf("%s", p->nombre); printf("Calle: "); scanf("%s", p->dir.calle); printf("Ciudad: "); scanf("%s", p->dir.ciudad); printf("Provincia: "); scanf("%s", p->dir.provincia); printf("Edad: "); scanf("%u", &p->edad); } 8.5 Typedef Permite crear un 'alias' de un tipo de C o para uno creado con struct. Sintaxis: typedef tipo_existente alias; typedef unsigned char byte; byte dato; /* unsigned char dato; */ Podemos usar typedef para crear alias para estructuras. Por ejemplo: typedef struct { typedef struct { char calle[30]; char nombre[35]; char ciudad[20]; t_direccion dir; }t_direccion; unsigned int edad; } t_datos_per; t_datos_per personas[5]; /* array de tipo t_datos_per */ Página 16 de 16