Arreglos Felipe Osorio Instituto de Estadı́stica Pontificia Universidad Católica de Valparaı́so Marzo 16, 2015 1 / 11 Arreglos en C I Un arreglo en C corresponde a un conjunto de datos ordenados del mismo tipo. I Un arreglo es sólo un bloque de memoria contiguo con esquema de indexado implicito. I En muchos cálculos cientı́ficos es necesario manipular matrices y vectores 2 / 11 Concepto de arreglo En términos esquemáticos un arreglo permite almacenar el conjunto: A = {a0 , a1 , . . . , am }. Se suele anotar matrices (arreglos 2D) y vectores (arreglos 1D), respectivamente como: a1 a11 a12 . . . a1c a2 a21 a22 . . . a2c a = . . A= . .. .. , .. .. . . an ar1 ar2 . . . arc Observación: En C los arreglos siempre inician con el ı́ndice 0, i.e. a0 .1 1 Índice 0 es ’bueno’ para máquinas, pero es ’malo’ para humanos. 3 / 11 Definiendo arreglos Considere la siguiente escala de grises con 256 tonalidades: Sin embargo, deseamos tener códigos en el intervalo (0, 1) /* definimos un vector de ’ largo ’ 256 */ double grises [256]; for ( int i = 0; i < 256; i ++) { /* asignamos valores entre 0 y 1 */ grises [ i ] = ( double ) i / 255; } 4 / 11 Inicializando arreglos Es posible asignar valores en el momento de definir un arreglo, p.ej: int accum [5] = {0 , 0 , 0 , 0 , 0}; double datos [10] = {100.0 , 300.0 , 500.5} ; los demás elementos del vector datos son inicializados con ceros. Observaciones: I No es recomendable confiar en este mecanismo de inicialización por defecto. I Es usual inicializar arreglos mediante un ciclo for. I Usar arreglos sin inicializar puede llevar a resultados impredecibles. 5 / 11 Definiendo un arreglo 2D Deseamos almacenar una matriz de a11 a21 A= a31 a41 4 filas × 5 columnas (es decir 20 elementos) a12 a13 a14 a15 a22 a23 a24 a25 . a32 a33 a34 a35 a42 a43 a44 a45 Es posible definir un arreglo bi-dimensional, mediante: /* definimos un arreglo 2 D */ double a [4][5] = {0.0}; /* acceder al primer elemento de ’a ’ */ a [0][0] = 1.0; 6 / 11 Definiendo un arreglo 2D # include < stdio .h > main () { int i , j , k = 0 , nrow = 4 , ncol = 5; double a [4][5] = {0.0} , accum = 0.; for ( i = 0; i < nrow ; i ++) { for ( j = 0; j < ncol ; j ++) { k ++; a [ i ][ j ] = k ; accum += a [ i ][ j ]; } } /* imprime el contenido de ’a ’ */ for ( i = 0; i < nrow ; i ++) { for ( j = 0; j < ncol ; j ++) printf ( " %6.4 g " , a [ i ][ j ]); printf ( " \ n " ); } printf ( " \ n " ); printf ( " La suma de todos los elementos de ’a ’ es % g \ n " , accum ); return ; } 7 / 11 Almacenando una matriz en un arreglo 1D # include < stdio .h > main () { int i , j , k = 0 , nrow = 4 , ncol = 5 , lda = 4; double a [20] = {0.0} , accum = 0.; for ( i = 0; i < nrow ; i ++) { for ( j = 0; j < ncol ; j ++) { k ++; a [ i + j * lda ] = k ; accum += a [ i + j * lda ]; } } /* imprime el contenido de ’a ’ */ for ( i = 0; i < nrow ; i ++) { for ( j = 0; j < ncol ; j ++) printf ( " %6.4 g " , a [ i + j * lda ]); printf ( " \ n " ); } printf ( " \ n " ); printf ( " La suma de todos los elementos de ’a ’ es % g \ n " , accum ); return ; } 8 / 11 Almacenando una matriz en un arreglo 1D Ejercicio: Suponga que deseamos sumar todos los elementos de la siguiente matriz: 1 2 3 A = 4 5 6 . 7 8 9 El programa requiere solo una pequeña modificación del código anterior (la clave es usar la variable lda, i.e. “la dimensión dominante” en conjunto con redefinir nrow y ncol). 9 / 11 Cálculo de: y = ax + y Ejemplo: Un cálculo bastante usual para realizar operaciones con matrices se conoce como axpy, el que está dado por y = ax + y, donde x, y son vectores con n elementos y a ∈ R. 10 / 11 Cálculo de: y = ax + y # include < stdio .h > main () { /* axpy : y <- a * x + y */ int i , n = 10; double x [10] = {0.0} , y [15] = {0.0} , a = -1.0; /* inicialización */ x [0] = 0.0; x [1] = 1.0; for ( i = 2; i < n ; i ++) { x [ i ] = x [i -2] + x [i -1]; y [ i ] = ( double ) i ; } /* retorno ’ rápido ’ */ if ( a == 0.0) return ; /* axpy */ for ( i = 0; i < n ; i ++) y [ i ] += a * x [ i ]; /* impresión */ printf ( " y : " ); for ( i = 0; i < n ; i ++) printf ( " %6.4 g " , y [ i ]); printf ( " \ n " ); return ; } 11 / 11