Muchas aplicaciones requieren el procesamiento de múltiples datos que tienen características comunes. En tales situaciones es conveniente colocar los datos en un arreglo (array).
Un arreglo es un conjunto de datos contiguos del mismo tipo con un tamaño fijo definido al momento de crearse.
A cada elemento (dato) del arreglo se le asocia una posición particular, la cual se requiere indicar para acceder a un elemento en específico. Esto se logra a través del uso de índices.
Los arreglos pueden ser unidimensionales o multidimensionales; de igual manera, se utilizan para hacer más eficiente el código de un programa.
Cada elemento del arreglo (cada dato individual) es referenciado mediante la especificación del nombre del arreglo, seguido por uno o más índices, con cada índice encerrado entre paréntesis cuadrados. Cada índice debe ser expresado como un entero no negativo.
Así, en un arreglo de n elementos, los elementos del arreglo son los siguientes:
La primera localidad del arreglo corresponde al índice 0 y la última corresponde al índice n-1, donde n es el tamaño del arreglo.
El valor de cada índice puede ser expresado como una constante entera, una variable entera o una expresión entera más compleja.
El número de índices determina la dimensión del arreglo; por ejemplo:
Se pueden formular arreglos de mayor dimensión, añadiendo índices adicionales de la misma manera (por ejemplo, z[i] [j] [k]).
Los arreglos se definen como las variables normales, acompañando a cada nombre de arreglo con una especificación de tamaño (número de elementos). Cabe aclarar que todos los elementos serán del mismo tipo de datos.
La sintaxis para definir un arreglo en lenguaje C es la siguiente:
Nota: Los tipos de datos estructuras no se abordarán en esta práctica.
Para inicializar los valores de un arreglo, estos deben aparecer en el orden en que serán asignados a los elementos individuales del arreglo, encerrados entre llaves y separados por comas. La forma general es…
tipoDato arreglo[expresión] = {valor 1, valor 2, . . ., valorN};
Donde valor1 se refiere al valor del primer elemento del arreglo, valor2 al valor del segundo elemento y así sucesivamente.
La presencia de la expresión, que indica el número de elementos del arreglo, es opcional cuando están presentes los valores iniciales.
Ejemplos
int digitos[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
float x[6] = {0, 0.25, 0, -0.50, 0, 0};
Todos los elementos del arreglo que no tienen asignados valores iniciales explícitos serán puestos automáticamente a cero. Esto incluye al resto de los elementos de un arreglo en el que un cierto número de elementos tiene asignado un valor distinto de cero.
Ejemplos
int valores[10] = {3, 3, 3};
float datos[6] = {-0.3, 0, 0.25};
El tamaño del arreglo no necesita ser especificado explícitamente cuando se incluyen los valores iniciales como una parte de la definición del arreglo. Con un arreglo numérico, el tamaño del arreglo será fijado automáticamente igual que el número de valores incluidos dentro de la definición.
int digitos[ ] = {1, 2, 3, 4, 5, 6};
float x[ ] = {0, 0.25, 0, -0.5};
Las cadenas de caracteres (arreglos de caracteres) son manejadas de modo algo diferente. En particular, cuando se le asigna una cadena de caracteres constante a un arreglo, como parte de la definición, la especificación del tamaño del arreglo normalmente se omite.
El tamaño adecuado será asignado automáticamente. Esto incluirá la provisión para el carácter nulo '\0', que se añade automáticamente al final de cada cadena de caracteres.
Ejemplo
char color[ ] = "ROJO";
Algunas veces es conveniente definir el tamaño de un arreglo en términos de una constante simbólica, en vez de una cantidad entera fija. Esto hace más fácil modificar un programa que utiliza un arreglo, ya que todas las referencias al tamaño máximo del arreglo (por ejemplo, en ciclos for o en definiciones de arreglos) pueden ser alteradas cambiando simplemente el valor de la constante simbólica.
Código (arreglo unidimensional con while)
Código (arreglo unidimensional con for)
Código (manejo de cadenas)
Lenguaje C permite crear arreglos de varias dimensiones, con la siguiente sintaxis:
Un arreglo unidimensional de n elementos puede ser visto como una lista de valores (o un vector). Análogamente, un arreglo bidimensional de m x n puede ser visto como una tabla (o una matriz) de valores que tienen m renglones y n columnas.
De manera práctica se puede considerar que la primera dimensión corresponde a los renglones, la segunda a las columnas, la tercera al plano, y así sucesivamente; sin embargo, en la memoria cada elemento del arreglo se guarda de forma contigua.
Ejemplo
float tabla[50] [50];
char pagina[24] [80];
double registros [100] [66] [255];
Se debe tener cuidado en el orden en que los valores iniciales se asignan a los elementos del arreglo multidimensional. La regla es que el último índice (extremo derecho) es el que se incrementa más rápidamente, y el primer índice (extremo izquierdo) es el que se incrementa más lentamente.
Así, los elementos de un arreglo bidimensional deben ser asignados por filas; esto es, primero serán asignados los elementos de la primera fila, luego los elementos de la segunda, y así sucesivamente.
int valores[3] [4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
El orden natural en el que los valores iniciales son asignados se puede alterar formando grupos de valores iniciales encerrados entre llaves ({ ... }). Los valores dentro de cada par interno de llaves serán asignados a los elementos del arreglo, cuyo último índice varíe más rápidamente.
Si hay pocos elementos dentro de cada par de llaves, al resto de los elementos de cada fila se le asignarán ceros. Por otra parte, el número de valores dentro de cada par de llaves no puede exceder del tamaño de fila definido.
Ejemplo
int valores [3] [4] = { {l, 2, 3, 4} , {5, 6,7, 8} , {9, 10, 11, 12} };
Para un arreglo tridimensional:
int t[2] [3] [4] = {
{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
} , {
{21, 22, 23, 24},
{25, 26, 27, 28},
{29, 30, 31, 32}
}
} ;
Código (arreglos multidimensionales)
Un apuntador almacena la dirección de memoria de la variable a la que apunta.
Dentro de la memoria, cada dato almacenado ocupa una o más celdas contiguas de memoria. El número de celdas de memoria requeridas para almacenar un dato depende de su tipo.
Una vez obtenida la dirección se asigna a otra variable de tipo apuntador ap:
ap = &var
Esta nueva variable ap es un apuntador a var, puesto que “apunta” a la dirección de memoria donde se almacena var.
No se debe olvidar que ap representa la dirección de var y no su valor.
El dato representado por var (el dato almacenado en las celdas de memoria de var) puede ser accedido mediante la expresión *ap, donde * es un operador monario llamado el operador indirección que sólo opera sobre una variable apuntador.
Por lo tanto, *ap y var representan el mismo dato (el contenido de las celdas de memoria).
Además, si tenemos: ap = &var y var2 = *ap
Entonces var y var2 representan el mismo valor; esto es, el valor de var se asigna indirectamente a var2 (asumiendo que var y var2 son declaradas con el mismo tipo de dato).
Los apuntadores, al igual que cualquier otra variable, deben ser declarados antes de ser usados en un programa; sin embargo, la declaración de un apuntador es un poco diferente, ya que el nombre de la variable debe ir precedido por un asterisco.
La sintaxis para declarar un apuntador es:
tipoDeDato *nombre_apuntador;
Los apuntadores sólo pueden apuntar a direcciones de memoria del mismo tipo de dato con el que fueron declarados.
Código (apuntadores)
Los apuntadores están muy relacionados con los arreglos y proporcionan una vía alternativa de acceso a los elementos individuales del arreglo. En realidad, el nombre de un arreglo es un apuntador al primer elemento de ese arreglo.
Si x es un arreglo unidimensional, entonces la dirección al primer elemento del arreglo se puede expresar tanto como &x[0] o simplemente como x; además, la dirección del segundo elemento del arreglo se puede escribir tanto como &x[1] o como (x + 1) y así sucesivamente.
En general, para un elemento i del arreglo se puede escribir &x[i] o bien (x+ i).
Cuando se escribe de la forma (x + i) el compilador de C ajusta automáticamente el número de celdas necesarias de acuerdo al tipo de dato del arreglo, así como también el desplazamiento u offset (valor de i).
Ahora que ya sabes cómo usar los arreglos de caracteres o cadenas, vamos a aplicar lo aprendido para realizar un programa que lea una cadena e imprima cuántas vocales tiene.
Por ejemplo:
Fundamentos de programación
A=3 E=2 I=1 O=3 U=1
Ahora que también aprendiste a utilizar arreglos bidimensionales para representar matrices, vas a hacer un programa en el que pidas datos enteros para llenar una matriz de 3x3 y luego mostrarás su traspuesta (la traspuesta se consigue intercambiando filas por columnas y viceversa).
Por ejemplo:
M = |
1 |
2 |
3 |
|
4 |
5 |
6 |
7 |
8 |
9 |
T = |
1 |
4 |
7 |
|
2 |
5 |
6 |
3 |
6 |
9 |
Para manejar conjuntos de datos de manera eficiente los lenguajes de programación cuentan con la definición de arreglos de diferentes dimensiones. Además, lenguaje C permite manejar estos conjuntos a través de apuntadores.
Fuentes de información
Solano, J., García, E., Sandoval, L., Nakayama, A., Arteaga, I. y Castañeda, M. (2016). Manual de prácticas del laboratorio de Fundamentos de programación. Facultad de Ingeniería. Consultado de http://lcp02.fi-b.unam.mx
Cómo citar
Arteaga, T. I. y Nakayama, M. A. (2018). Arreglos unidimensionales y multidimensionales. Unidades de Apoyo para el Aprendizaje. CUAED/Facultad de Ingeniería-UNAM. Consultado el (fecha) de (vínculo)