Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Introducción a los Computadores Arreglos en C Alejandro Piedrahita H. Instituto de Matemáticas Facultad de Ciencias Exactas y Naturales Universidad de Antioquia Copyleft «2013. Reproducción permitida bajo los términos de la licencia de documentación libre GNU. Documento bajo construcción, reportar errores al correo electrónico [email protected] Matrices Referencias Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Contenido 1 Introducción 2 Operaciones con arreglos unidimensionales 3 Paso de arreglos a funciones 4 Arreglos bidimensionales (matrices) 5 Operaciones con arreglos bidimensionales 6 Referencias Matrices Referencias Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Referencias Arreglos (arrays) Arreglo: concepto en programación análogo a los conceptos matemáticos de vector, matriz y tensor Arreglo unidimensional: estructura de datos formada por una colección finita de elementos homogéneos y ordenados que se que se referencian con un nombre común Homogéneos: todos los elementos son del mismo tipo de dato (int, float, etc.) Ordenados: el arreglo tiene un primer elemento, un segundo elemento, etc. Finito: el arreglo tiene un último elemento Los elementos de un arreglo se almacenan en posiciones consecutivas de memoria Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Referencias Declaración de arreglos Declaración de un arreglo unidimensional: tipo nombre arreglo[tama~ no] tipo: tipo de dato de los elementos del arreglo (int, float, etc.) nombre arreglo: identificador que representa la colección de elementos tamaño: constante entera positiva que representa la cantidad de elementos de la colección Ejemplos: double x[30]; float notas[8]; int posiciones[100]; char apellidos[15]; Los 30 elementos de x son: x[0] , x[1] , x[2] , ... , x[28] , x[29] Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Referencias Formato de inicialización de arreglos nombre arreglo[i] = valor; double y[3]; int z[4]; y[0] = 7; y[1] = 0.5; y[2] = -2.7183; z[0] = 12, z[1] = 4; z[2] = z[0] + 2*z[1]; z[3] = z[2]++; // Hace lo mismo que la asignación anterior char mensaje[] = "Todo bien"; double y[3] = {7, 0.5, -2.7183 }; char mensaje[10] = {’T’, ’o’, ’d’, /* Si no se precisa el tama~ no del arreglo, C lo asigna dado el número de elementos */ ’o’, ’ ’, ’b’, ’i’, ’e’, ’n’, ’\O’ }; double y[] = {7, 0.5, -2.7183}; double mensaje[10]; /* Si el tama~ no del arreglo supera al númmero de elementos, C asigna 0.0 al resto */ mensaje[0] = ’T’; mensaje[0] = ’o’; mensaje[0] = ’d’; . . . double y[7] = {7, 0.5, -2.7183}; Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Operaciones frecuentes Recorriendo un arreglo x[i] de tamaño n: El recorrido se realiza por medio de un ı́ndice El ı́ndice puede ir desde el primero hasta el último elemento Recorrido del primero al último for (i=0; i<n; i++) { // proceso que involucra a x[i] <proceso> } El ı́ndice puede ir desde el último hasta el primer elemento Recorrido del último al primero for (i=n-1; i>=0; i--) { // proceso que involucra a x[i] <proceso> } Referencias Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Referencias Ejemplo 2.1 (Notas) Escriba un programa en C que almacene en un vector (arreglo unidimensional) las notas finales de los alumnos de un curso formado por 10 estudiantes. El programa debe visualizar por pantalla las notas. Solución notas vector.c #include<stdio.h> main(){ float notas[10]; int i; // Recorrido para leer datos en el arreglo for (i=0; i<10; i++) { printf("Ingrese nota = "); scanf("%f", &notas[i]); } // Recorrido para escribir datos en pantalla for (i=0; i<10; i++) { printf("Nota %d = %f \n", i, notas[i]); } } Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Ejemplo 2.2 (Notas) Modifique el programa del ejemplo anterior (5.1) para que muestre por pantalla el promedio del curso. Solución notas promedio.c #include<stdio.h> main(){ float notas[10], suma = 0.0, promedio; int i; // Recorrido para leer datos en el arreglo for (i=0; i<10; i++) { printf("Ingrese nota = "); scanf("%f", &notas[i]); } // Recorrido para sumar las 10 notas for (i=0; i<10; i++) suma += notas[i]; promedio = suma/10.0; printf("Promedio = %f", promedio); } Referencias Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Referencias Ejemplo 2.3 (Fibonacci) Escriba un programa en C que genere los primeros n términos de la sucesión de Fibonacci, los almacene en un vector y los muestre por pantalla. Solución fib vector.c #include<stdio.h> main(){ int i, n; printf("Ingrese número de términos: "); scanf("%d", &n); /* Declara vector de tama~ no n e inicializa los dos primeros elementos */ int fib[n]; fib[0]=0, fib[1]=1; // Almacena Fibonacci for (i=2; i<n; i++) fib[i] = fib[i-1] + fib[i-2]; // Imprime términos de la sucesión for (i=0; i<n; i++) printf(" %d \t", fib[i]); } Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Referencias Ejemplo 2.4 (Intercambiar) Escriba un programa en C que intercambie los elementos de un vector de la siguiente manera: el de la primera posición pasa a la última posición, el de la segunda a la penúltima, etc. Solución intercambia vector.c #include<stdio.h> // Intercambia elementos del arreglo for (i=0; i<n/2; i++) { main(){ int i, n; temp = x[i]; x[i] = x[n-i-1]; x[n-i-1] = temp; printf("Ingrese tama~ no del vector: "); scanf("%d", &n); float x[n], temp; } // Escribe datos en el arreglo for (i=0; i<n; i++) { printf("Elemento %d: ", i); scanf("%g", &x[i]); } // continua en la columna derecha // Imprime los elementos del vector for (i=0; i<n; i++) printf(" %g \t", x[i]); } Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Referencias Ejemplo 2.5 (Intercambiar función) Escriba el programa del ejemplo anterior (2.4) utilizando funciones. Solución intercambiafun vector.c #include<stdio.h> // Intercambia elementos del arreglo for (i=0; i<n/2; i++) // declaracion de la funcion intercambia void intercambia(float *a, float *b); intercambia(&x[i], &x[n-i-1]); main(){ int i, n; printf("Ingrese tama~ no del vector: "); scanf("%d", &n); // Imprime los elementos del vector for (i=0; i<n; i++) printf(" %g \t", x[i]); } float x[n]; // Escribe datos en el arreglo for (i=0; i<n; i++) { // declaracion de la funcion intercambia void intercambia(float *a, float *b) { float temp; printf("Elemento %d: ", i); scanf("%g", &x[i]); temp = *a; *a = *b; *b = temp; } // continua en la columna derecha } Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Referencias Paso de un arreglo unidimensional (vector) como parámetro Cuando un argumento (parámetro) de una función es un arreglo, el parámetro (arreglo) se pasa por referencia tipo funcion(..., tipo x[], ...) { // cuerpo de la función . . . } La forma más usual de pasar un arreglo como parámetro a una función es por medio de punteros: tipo funcion(..., tipo *x, ...) { // cuerpo de la función . . . } Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Referencias Ejemplo 3.1 (Imprime arreglo) Escriba una función en C llamada imprimir que reciba como argumento un vector formado por 0, 1, 2, . . . , 9 y los muestre por pantalla. Solución pasar arreglo.c #include<stdio.h> #define n 10 // define n=10 /* declaracion de la funcion imprimir de dos maneras */ void imprimir1(int x[]); void imprimir2(int *x); // Definición de la funcion imprimir1 void imprimir1(int x[]) { int i; for (i=0; i<n; i++) printf(" %d \t", x[i]); } main(){ int x[n], i; // Inicializa arreglo for (i=0; i<n; i++) x[i] = i; imprimir1(x); // Imprime arreglo // imprimir2(x); } // continua en la columna derecha // Definición de la funcion imprimir2 void imprimir2(int *x) { int i; for (i=0; i<n; i++) printf(" %d \t", x[i]); } Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Referencias Ejemplo 3.2 Ejemplo 3.2 (promedio arreglo) Escriba un programa en C que calcule el promedio de los elementos de un vector de tamaño n. El programa debe constar de tres funciones, una que lea el vector (leer vector), otra que imprima el vector por pantalla (escribir vector) y otra que calcule el promedio (promedio). Solución Datos de entrada: n: tamaño del vector x[n]: vector Funciones: void leer vector(double x[], int n) void escribir vector(double x[], int n) double promedio(double x[], int n) Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Referencias promedio arreglo.c #include<stdio.h> // Declaracion de las funciones void leer vector(double x[], int n); void escribir vector(double x[], int n); double promedio(double x[], int n); main(){ int n; printf("Ingrese número de elementos: "); scanf("%d", &n); double x[n]; // Definición de las funciones void escribir vector(double x[], int n) { int i; for (i=0; i<n; i++) printf(" %5.8lf \t", x[i]); } double promedio(double x[], int n) { int i; double suma = 0.0; for (i=0; i<n; i++) suma += x[i]; leer vector(x, n); escribir vector(x, n); printf("\nPromedio = %lf", promedio(x,n)); } void leer vector(double x[], int n) { int i; for (i=0; i<n; i++) { printf("x( %d) = ", i+1); scanf("%lf", &x[i]); } } // continua en la columna derecha return suma/n; } Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Ejemplo 3.3 Ejemplo 3.3 (Busca elemento) Escriba una función en C que determine si un elemento dado está en un vector. Solución Datos de entrada: n: tamaño del vector x[n]: vector v: elemento a buscar Funciones: void leer vector(double x[], int n) void escribir vector(double x[], int n) int pertenece(double x[], double v, int n) Referencias Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Referencias buscar.c #include<stdio.h> // Declaracion de las funciones void leer vector(double x[], int n); void escribir vector(double x[], int n); int pertenece(double v, double x[], int n); // Definición de las funciones void leer vector(double x[], int n) { int i; for (i=0; i<n; i++) { printf("x( %d) = ", i+1); scanf("%lf", &x[i]); } main(){ int n; printf("Ingrese número de elementos: "); scanf("%d", &n); double x[n], v; } void escribir vector(double x[], int n) { int i; leer vector(x, n); escribir vector(x, n); printf("\nIngrese elemento a buscar: "); scanf("%lf", &v); if (pertenece(v,x,n)) printf(" %lf sı́ está", v); else printf(" %lf no está", v); for (i=0; i<n; i++) printf(" %5.8lf \t", x[i]); } int pertenece(double v, double x[], int n) { int s = 0, k = 0; while (s==0 && k<n) { if (v==x[k]) s=1; k++; } } return s; // continua en la columna derecha } Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Referencias Arreglos bidimensionales (matrices) Arreglo bidimensional: concepto en programación análogo al concepto matemático de matriz La definición de arreglo bidimensional [] puede hacerse desde dos enfoques: Enfoque recursivo: se trata de un arreglo unidimensional en el que cada elemento es a su vez un arreglo unidimensional Enfoque directo: estructura de datos formada por una colección finita de elementos homogéneos, ordenados cada uno de ellos en dos dimensiones y referenciados con un nombre común El acceso a un elemento del arreglo bidimensional se realiza mediante el nombre del arreglo (identificador ) y un par de ı́ndices que indican la “posición” del elemento Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Referencias Representación gráfica de un arreglo bidimensional Arreglo bidimensional con m filas (horizontales) y n columnas (verticales) ∗ ∗ ∗ ··· ··· ··· ··· ··· ··· .. . .. . ∗ : elemento [0][0] ∗ ∗ : elemento [0][2] ∗ : elemento [1][n-2] ∗ : elemento [2][1] ∗ ∗ : elemento [i][j] .. . ∗ ··· .. . ∗ : elemento [m-1][2] ∗ ∗ : elemento [m-1][n-1] Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Referencias Declaración de arreglos Declaración de un arreglo bidimensional: tipo nombre arreglo[filas][columnas] tipo: tipo de dato de los elementos del arreglo (int, float, etc.) nombre arreglo: identificador que representa la colección de elementos filas: constante entera positiva que representa la cantidad de filas columnas: constante entera positiva que representa la cantidad de columnas Ejemplos: double a[3][4]; int pos[18][24]; float matriz[12][8]; char lista[7][8]; Los 12 elementos de a son: a[0][0] , a[0][1] , x[0][2] , ... , a[2][2] , a[2][3] Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Referencias Formato de inicialización de arreglos bidimensionales nombre arreglo[i][j] = valor; double m[2][3]; m[0][0] m[0][1] m[0][2] m[1][0] m[1][1] m[1][2] = = = = = = 1.1; 1.2; 1.3; 1.4; 1.5; 1.6; // Hace lo mismo que la asignación anterior double m[2][3] = {1.1, 1.2, 1.3, 1.4, 1.5, 1.6 }; /* En el siguiente ejemplo se asignan ceros hasta completar las filas */ double m[][3] = {1.1, 1.2, 1.3, 1.4} double m[2][3]; m[0][0] m[0][1] m[0][2] m[1][0] m[1][1] m[1][2] = = = = = = 1.1; 1.2; 1.3; 1.4; 0.0; 0.0; // Hace lo mismo que la asignación anterior /* Las siguientes inicializaciones son INCORRECTAS */ double m[][3] = {1.1, 1.2, 1.3, 1.4, 1.5, 1.6 }; double x[][] = {1.1, 1.2, 1.3, 1.4} double y[2][] = {1.1, 1.2, 1.3, 1.4} Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Operaciones frecuentes Procesar fila i Procesa fila for (j=0; j<n; j++) { // proceso que involucra a a[i][j] <proceso a[i][j]> } Procesar columna j: Procesa columna for (i=0; i<n; i++) { // proceso que involucra a a[i][j] <proceso a[i][j]> } Matrices Referencias Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Operaciones frecuentes Recorrido de un arreglo a[i][j] de tamaño m×n: Recorrido por filas for (i=0; i<n; i++) { for (j=0; j<n; j++) { // proceso que involucra a a[i][j] <proceso a[i][j]> } } Recorrido por columnas for (j=0; j<n; j++) { for (i=0; i<n; i++) { // proceso que involucra a a[i][j] <proceso a[i][j]> } } Matrices Referencias Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Referencias Ejemplo 5.1 Ejemplo 5.1 (Cine) Escriba un programa en C que almacene en una matriz (arreglo bidimensional) el número de personas que ingresan a una sala de cine X durante cada uno de los dı́as de la semana. La matriz debe constar de dos columnas, la primera para los dı́as de la semana y la segunda para el número de personas, y siete filas para cada uno de los dı́as de la semana. El programa debe calcular el promedio de personas que ingresan a la sala. Solución Matriz: int asistencia[2][7] asistencia[i][1]: número de personas que asisten el dı́a i Salida: promedio = (asistencia[0][1] + · · · + asistencia[6][1])/7 Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales cine.c Matrices Referencias /* Almacena los dı́as en la primera columna */ for (i=0; i<7; i++) #include<stdio.h> main(){ asistencia[i][0] = i+1; int i, j, total = 0, asistencia[7][2]; float promedio; /* Almacena el número de personas en la segunda columna */ for (i=0; i<2; i++) { // Inicializa arreglo a cero for (i=0; i<7; i++) { printf("Personas dı́a %d: ", i+1); for (j=0; j<2; j++) { scanf("%d", &asistencia[i][1]); asistencia[i][j] = 0; } } // Muestra información del arreglo for (i=0; i<7; i++) { } printf("El dı́a %d asisten %d \n", // Muestra arreglo inicializado a cero for (i=0; i<7; i++) { asistencia[i][0], asistencia[i][1]); for (j=0; j<2; j++) { } printf(" %d ", asistencia[i][j]); // Cálculo del promedio for (i=0; i<7; i++) } printf("\n"); // cambia de fila total += asistencia[i][1]; } promedio = (float)total/7.0; // continua en la columna derecha printf("Promedio = %f", promedio); } Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Bibliografı́a I O. Cairó Metodologı́a de la programación Segunda edición. Alfaomega Grupo Editor, S.A., 2005 M.A. Criado Programación en lenguajes estructurados Alfaomega Grupo Editor, S.A. de C.V. Primera Edición, 2006 B.W. Kernighan, D. Ritchie The C Programming Language Prentice Hall, 2th Edition, 1988 S. Lipschutz Schaum’s Outline of Essential Computer Mathematics McGraw-Hill, 1th edition, 1982 H.M. Mora Escobar Introducción a C y a métodos numéricos Universidad Nacional de Colombia (Sede Bogotá), 2004 Referencias Introducción Vectores Paso de arreglos a funciones Arreglos bidimensionales Matrices Referencias Bibliografı́a II M.J. Páez C y C ++ de afán Universidad de Antioquia, 2004 R. Séroul Programming for Mathematicians Springer, 2000 E. Scheinerman C ++ for Mathematicians: An Introduction for Students and Professionals Taylor & Francis Group, LLC, 2006 A. Shen Algorithms and Programming Springer Undergraduate Texts in Mathematics and Technology, 2010 P. Tymann Schaum’s Outline of Principles of Computer Science McGraw-Hill, 1th edition, 2008