Академический Документы
Профессиональный Документы
Культура Документы
Vectores y Matrices
OBJETIVO En temas anteriores hemos declarado variables simples de tipo int, float, o de cualquier otro tipo simple. A menudo necesitaremos declarar una coleccin de variables, tales como 20 enteros. En este tema veremos cmo podemos declarar arrays vectores y matrices, que reciben el nombre genrico de arrays. Por otro lado, C no tiene datos predefinidos tipo cadena. En su lugar, C manipula cadenas de caracteres mediante arrays de caracteres que terminan con el carcter nulo ASCII ('\0'). Una cadena se considera como un vector de tipo char o unsigned char. Bibliografa Joyanes Aguilar, J. Programacin en C++. Algoritmos, estructuras de datos y Objetos. Captulos 7 y 9. Ed. McGraw-Hill. Pont, M.J. Software Engineering with C++ and CASE Tools. Captulo 7. Pointers and arrays. Ed. Addison-Wesley. CONTENIDOS 1. Qu es un Array? 1.1. Elementos de un Array 1.2. Declaracin de arrays 1.3. Asignacin de valores fuera del array 1.4. Inicializacin de un array 2. Matrices (arrays multidimensionales) 2.1. Inicializacin de arrays multidimensionales 3. Cadena de caracteres 3.1. Lectura de cadenas 3.2. Manejo de cadenas 1 2 3 4 6 6 7 9 10 11
1. Qu es un Array?
Un array es una coleccin de posiciones de almacenamiento de datos, todos ellas con el mismo tipo de dato. Cada posicin de almacenamiento se denomina elemento del array. Denominaremos vector a un array unidimensional, y matriz a un array multidimensional. Para declarar un vector escribimos el tipo de dato, seguido del nombre del vector y del subndice. El subndice es el nmero de elementos del vector, encerrado entre corchetes. Por ejemplo, long vectorLargo[25]; declara un vector de 25 enteros largos, llamado vectorLargo. Cuando el compilador encuentra esta declaracin reserva la memoria necesaria para los 25 elementos. Puesto que cada entero necesita 4 bytes, esta declaracin reserva 100 bytes contiguos de memoria, como se ilustra en la figura 9.1.
Vectores y Matrices
Programa 9.1: Uso de un vector entero 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: // Listado 9.1: Vectors #include <stdio.h> int main() { int Vector1[5]; int i; for ( i=0; i<5; i++) // 0-4 { printf("Valor para Vector1[%d]: ", i); scanf("%d", &Vector1[i]); } for (i = 0; i<5; i++) printf("%d: %d\n", i, Vector1[i]); return 0; }
Salida Valor Valor Valor Valor Valor 0: 1 1: 2 para para para para para Vector1[0]: Vector1[1]: Vector1[2]: Vector1[3]: Vector1[4]: 1 2 3 4 5
Vectores y Matrices
2: 3 3: 4 4: 5
Anlisis: La lnea 6 declara un vector llamado Vector1, que contiene cinco variables enteras. La lnea 8 establece un bucle que cuenta de 0 a 4, que es el adecuado conjunto de desplazamientos para un vector de cinco elementos. Los sucesivos valores introducidos por el usuario son asignados a los correspondientes elementos del vector. El segundo bucle imprime cada uno de los valores del vector en la pantalla. NOTA: los vectores cuentan desde 0, no desde 1. Este es el origen de muchos errores en programas C escritos por principiantes. Siempre que utilices un vector, recuerda que un vector con 10 elementos cuenta desde NombreVector[0] hasta NombreVector[9]. NombreVector[10] no se usa.
Anlisis: La lnea 7 crea una enumeracin llamada DiasSemana que tiene ocho miembros. Lunes es igual a cero, y DiasEnSemana es igual a 7.
Vectores y Matrices
La lnea 11 usa la constante enumerada viernes como ndice del vector. Puesto que viernes vale 4, el quinto elemento del vector, ArraySemana[4] se imprime en pantalla.
Vectores y Matrices
26: 27: printf("\nTest 2: \n"); 28: printf("paseoZorrilla[0] : %d\n", paseoZorrilla[0] ); 29: printf("paseoZorrilla[20]: %d\n", paseoZorrilla[20]); 30: printf("paseoZorrilla[21]: %d\n", paseoZorrilla[21]); 31: for (i = 0; i<3; i++) 32: printf("calleUno[%d]: %d\n", i, calleUno[i]); 33: 34: for (i = 0; i<3; i++) 35: printf("calleDos[%d]: %d\n", i, calleDos[i]); 36: 37: return 0; 38: }
Salida del programa Test 1: paseoZorrilla[0] : 0 paseoZorrilla[20]: 20 Asignando... Test 2: paseoZorrilla[0] : 0 paseoZorrilla[20]: 20 paseoZorrilla[21]: 21 calleUno[0]: 20 calleUno[1]: 21 calleUno[2]: -1 calleDos[0]: -2 calleDos[1]: -2 calleDos[2]: -2
Anlisis: Primero se declaran dos vectores de tres enteros que actan como centinelas alrededor de paseoZorrilla. Estos vectores centinelas se inicializan con los valores -1 y -2. Si escribimos algo en la memoria despus del final de paseoZorrilla, alguno de los centinelas cambiar probablemente de valor. Algunos ordenadores asignan memoria de arriba abajo (de direcciones altas a direcciones bajas) mientras que otros lo hacen de abajo hacia arriba (de direcciones bajas a direcciones altas). Por esta razn, hemos colocado centinelas a ambos lados de paseoZorrilla. Despus se asignan valores a los miembros de paseoZorrilla, pero el contador cuenta hasta los subndices 20 y 21, que no existen en paseoZorrilla. Podemos observar que al imprimir paseoZorrilla[20] se escribe sin ningn problema el valor 20. Sin embargo, cuando se imprimen calleUno y calleDos, observamos que calleUno[0] ha cambiado. Esto se debe que la zona de memoria de paseoZorrilla[20] coincide con la zona de memoria de calleUno[0].
Vectores y Matrices
Vectores y Matrices
Figura 9.2. Un tablero de ajedrez y una matriz. La declaracin de una matriz que represente un tablero de ajedrez podra ser: int tablero[8][8]; Tambin podramos representar los mismos datos con una matriz de 64 elementos. Por ejemplo int tablero[64]; Esto no tiene una correspondencia tan directa con el mundo real como la matriz. Al comienzo de la partida el rey est situado en la cuarta posicin de la primera fila. En la matriz esta posicin corresponde a tablero[0][3]; suponiendo que el primer subndice corresponde a la fila y el segundo a la columna. La disposicin de las posiciones del tablero completo se muestra en la figura 9.2.
Vectores y Matrices
El listado 9.4 crea una matriz bidimensional. La primera dimensin contiene los nmeros del 0 al 4. La segunda dimensin consta de los valores que duplican los valores de la primera dimensin. Programa 9.4: Creacin de una matriz multidimensional 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: #include <stdio.h> int main() { int i,j; int matriz[5][2] = { {0,0}, {1,2}, {2,4}, {3,6}, {4,8}}; for (i = 0; i<5; i++) { for (j=0; j<2; j++) { printf("matriz[%d][%d] = ", i, j); printf("%d \t", matriz[i][j]); } printf("\n"); } return 0; }
Salida del programa matriz[0][0] matriz[1][0] matriz[2][0] matriz[3][0] matriz[4][0] = = = = = 0 1 2 3 4 matriz[0][1] matriz[1][1] matriz[2][1] matriz[3][1] matriz[4][1] = = = = = 0 2 4 6 8
Anlisis: La lnea 5 declara matriz como matriz bidimensional. La primera dimensin consta de cinco enteros; la segunda dimensin consta de dos enteros. Esto crea una estructura como la de la figura 9.3.
Figura 9.3. Una matriz de 5x2. Los valores se inicializan por parejas. Las lneas 7 y 8 crean un bucle anidado. El bucle externo recorre los elementos de la primera dimensin. Para cada miembro de esta dimensin, el bucle interno recorre cada uno de los miembros de la segunda dimensin. Esto es consistente con la salida. Al elemento matriz[0][0] le sigue el elemento matriz[0][1]. Una vez que el ndice de la segunda dimensin ha recorrido todos los elementos de dicha dimensin, el ndice de la primera dimensin se incrementa y el ndice de la segunda dimensin vuelve a empezar en cero.
Vectores y Matrices
3. Cadena de caracteres
Una cadena es una serie de caracteres. Las nicas cadenas que hemos visto hasta ahora son las cadenas constantes que utilizamos en las sentencias con printf(), tal como printf("Hola mundo"; C no tiene datos predefinidos tipo cadena. En su lugar, C manipula cadenas de caracteres mediante vectores de de caracteres que terminan con el carcter nulo ASCII ('\0'). Una cadena se considera como un vector de tipo char o unsigned char. Podemos declarar e inicializar una cadena del mismo modo que cualquier otro vector. El tipo base, naturalmente, es char, o bien, unsigned char. Por ejemplo, char texto[80]; char Saludo[] = { 'H', 'o', 'l', 'a', , ' ', 'M','u','n','d','o', '\0' }; El ltimo carcter, '\0', es el carcter nulo, que muchas funciones C reconocen como terminador de una cadena. Aunque este procedimiento de inicializar un vector carcter-a-carcter es correcto, es difcil de escribir y es una fuente potencial de posibles errores. C nos permite usar una forma simplificada de la lnea de cdigo anterior. Esto es char Saludo[] = "Hola Mundo"; Hay dos observaciones importantes sobre esta sintaxis: En lugar de caracteres entre comillas simples separados por comas y encerrados entre llaves, se utiliza una cadena de caracteres encerrada entre dobles comillas, sin comas y sin llaves. No es necesario aadir el carcter nulo porque el compilador lo hace de forma automtica.
La cadena Hola Mundo tiene 11 bytes: Hola tiene 4 bytes, el espacio 1 byte, Mundo 5 bytes, y el carcter nulo 1 byte. Tambin podemos crear cadenas de caracteres sin inicializar. Al igual que con todos los vectores, es importante asegurar que no vamos a utilizar ms espacio del reservado. El listado 9.5 muestra el uso de un vector sin valores iniciales. Programa 9.5. Rellenado de una cadena 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: /* Listado 7.9: rellenado de un vector */ #include <stdio.h> int main() { char buffer[80]; printf("Escriba la cadena: "); scanf("%s", buffer); printf("Este es el buffer: %s\n", buffer); return 0; }
Vectores y Matrices
10
Salida del programa Escriba la cadena: hola mundo Este es el buffer: hola
Anlisis: En la lnea 6 se declara un buffer para 80 caracteres, tamao suficientemente grande para contener una cadena de 79 caracteres y el carcter nulo para cerrar la cadena. En la lnea 7, se pide al usuario que introduzca una cadena, que se almacena en buffer en la lnea 8. Este programa presenta dos problemas. Primero, si el usuario teclea ms de 79 caracteres, scanf() escribir ms all del final de buffer. Segundo, si el usuario introduce un espacio, scanf() considera que es el final de la cadena y no escribe ms caracteres en buffer. Los caracteres tecleados despus del espacio se pierden.
Listado 9.6. Rellenado de una cadena con gets() 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: /* Listado 7.10: rellenado de una cadena */ #include <stdio.h> int main() { char buffer[80]; printf("Escriba la cadena: "); gets(buffer); printf("Este es el buffer: %s\n", buffer); return 0; }
Salida del programa Escriba la cadena: Hola Mundo Este es el buffer: Hola Mundo
Vectores y Matrices
11
Anlisis: En la lnea 2 se incluye el archivo de cabecera string.h. Este archivo contiene el prototipo de la funcin strcpy(). strcpy() toma dos cadenas de caracteres una cadena destino seguido de una cadena origen. Si la cadena origen es ms larga que la cadena destino, strcpy() podra escribir fuera del buffer, ms all del ltimo elemento del mismo. Vectores Para declarar un vector, escribe el tipo de variable a almacenar, seguido del nombre del vector y de un ndice con el nmero de elementos que tendr el vector. Ejemplo: int vectorDeEnteros[90]; Para acceder a los miembros de un vector, se utiliza el operador subndice, []. Ejemplo: int ElNovenoEntero = VectorDeEnteros [8]; Los vectores cuentan desde cero. Un vector de n elementos se numera de 0 a n-1.
Vectores y Matrices
12
Nota del profesor: si detectas algn error, o hay alguna parte confusa, o piensas que sobra o falta alguna seccin, por favor, enviadme un mensaje a josdie@tel.uva.es. Gracias por anticipado. Vuestras sugerencias se utilizarn para mejorar estos apuntes.