Enlaces a sitios institucionales

Arreglos

Unidad de Apoyo para el Aprendizaje

Iniciar

Introducción

En una computadora podemos realizar los cálculos o almacenar información, para lo cual utilizamos variables. Así, una variable puede, por ejemplo, almacenar el cálculo de un área o el resultado de un procedimiento; sin embargo, ¿qué pasa si queremos guardar cientos o miles de cálculos o resultados?, ¿se tendrían que crear cientos o miles de variables? La respuesta es no; para eso existen los arreglos.

Un arreglo es la estructura de datos más simple que puede manejar un lenguaje de programación. Permite definir un número finito de variables de un mismo tipo, todas al mismo tiempo. Existen arreglos contiguos y ligados.

Ilustración de programador en la laptop

La creación y manipulación de arreglos unidimensionales y multidimensionales constituye un aspecto fundamental en la programación, ya que permite organizar y gestionar diferentes tipos de datos como cadenas, valores enteros y valores reales. Este tema es básico en cualquier lenguaje de programación y resulta indispensable para quienes se inician en el área. En este caso se emplea el lenguaje C como ejemplo, aunque los conceptos de arreglos pueden extrapolarse a otros lenguajes con los mismos resultados.

Una propiedad importante de los arreglos es que permiten manipular una gran cantidad de datos contiguos y homogéneos, lo que los convierte en una estructura de datos fundamental para inteligencia artificial (IA) y machine learning; por lo tanto, estos conceptos son útiles y fundamentales para personas interesadas en programación y para personas interesadas en ciencia de datos e inteligencia artificial.

Objetivo

Reconocer la importancia y utilidad de los arreglos unidimensionales y multidimensionales de diferentes tipos de datos mediante su creación, utilización y manipulación para dar solución a problemas computacionales.

Arreglos

Un arreglo es un conjunto de datos del mismo tipo, que puede ser unidimensional o multidimensional. A cada elemento (dato) del arreglo se le asocia una posición particular. Para acceder a los elementos de un arreglo es necesario utilizar un índice, como se muestra en el siguiente ejemplo.

Arreglo unidimensional

Arreglos contiguos y ligados

Revisa enseguida cómo se entiende cada uno de estos arreglos.

Arreglos contiguos

Un arreglo contiguo es aquél que se define con un tamaño fijo y cuyas localidades de memoria se reservan de manera aledaña, una después de otra; por lo tanto, se puede acceder a cada elemento del conjunto utilizando un índice.

Arreglos ligados

Un arreglo ligado permite que el tamaño sea variable; por lo tanto, es posible redimensionar su tamaño durante la ejecución del programa, utilizando de manera más eficiente la memoria (se reserva sólo la memoria que se ocupa). Para crear un arreglo ligado se debe utilizar lo que se conoce como memoria dinámica. Para acceder a un elemento del arreglo se utiliza una referencia, no un índice.

En este tema nos enfocaremos en los arreglos contiguos. En la siguiente imagen se observa la anatomía de un arreglo.

Anatomía de un arreglo

Ahora entendamos la diferencia entre arreglos unidimensionales y multidimensionales.

Arreglos unidimensionales

Los arreglos unidimensionales están constituidos por localidades de memoria contiguas ordenadas bajo un mismo nombre y sobre un solo nivel (una dimensión).

Arreglos multidimensionales

Los arreglos multidimensionales están constituidos por localidades de memoria contiguas ordenadas bajo un mismo nombre y que pueden tener varios niveles (varias dimensiones) que van desde el plano (dos dimensiones) hasta la enésima dimensión.

En lenguaje C, la primera localidad de un arreglo tiene el índice 0 y la última localidad tiene el índice n-1, donde n es el tamaño del arreglo. La declaración de un arreglo en C sigue la sintaxis general:

tipo_dato nombre_arreglo[tam1][tam2]...[tamN];

Donde cada corchete representa la dimensión del arreglo.

Arreglo unidimensional

Para declarar un arreglo unidimensional de cinco elementos enteros, la sintaxis es la siguiente:

int arr[5];

Para acceder a un elemento específico en un arreglo unidimensional, se utiliza el índice del elemento. Por ejemplo, en un arreglo unidimensional A, un elemento en la posición 3 se accede como A[2] (recordar que el índice inicia en 0; por lo tanto, el tercer elemento está en la posición 2). La siguiente imagen muestra una representación en memoria de un arreglo unidimensional.

Representación en memoria de un arreglo unidimensional
Icono de programación

Ejemplo:

Programa que imprime las direcciones de memoria de los elementos de un arreglo unidimensional en lenguaje C.




#include<stdio.h>
int main(){
    // Se declara un arreglo ligado
    short nums[] = {5,4,3,2,1}, cont;
    // Se recorre el arreglo creado
    for (cont = 0; cont < 5 ; cont++)
        // Se imprime cada dirección de memoria del arreglo
        printf("%p\n", &nums[cont]);
        // El símbolo "&" indica la referencia a la dirección de memoria
  return 0;
}

Ejemplo de salida:

0x7ff7b038402e
0x7ff7b0384030
0x7ff7b0384032
0x7ff7b0384034
0x7ff7b0384036

Nota: El compilador de lenguaje C puede emitir advertencias y errores al compilar un programa. Recuerda que una advertencia no impide la generación del ejecutable (.exe o .out), pero un error sí lo hace; sin embargo, trata de atender todas las advertencias que marca el compilador, para evitar errores en tiempo de ejecución.

También es posible declarar un arreglo con un tamaño definido en tiempo de ejecución. Este tipo de arreglo también es contiguo:


#include <stdio.h>
int main(){
    int size = 0;
    printf("Ingresa el tamaño del arreglo: ");
    scanf("%d", &size);
    int arr[size];
    for (int cont=0; cont<size; cont++)
        printf("%p\n", &arr[cont]);
    return 0;
}

Ejemplo de salida:

Ingresa el tamaño del arreglo: 5
0x7ff7b86b1fd0
0x7ff7b86b1fd4
0x7ff7b86b1fd8
0x7ff7b86b1fdc
0x7ff7b86b1fe0

En lenguaje C, las cadenas se deben almacenar en arreglos; así, una oración se tiene que guardar como un arreglo de caracteres. Para manejar una cadena se usa el especificador de formato %s (tanto para leer como para imprimir el valor).

Las palabras se leen con la función scanf, mientras que las oraciones se leen con la función gets. Cuando se está leyendo de teclado es recomendable borrar el buffer para evitar que se queden caracteres en el buffer de entrada. Para limpiar el buffer se pueden usar las funciones fflush o setbuf. A continuación, se muestra un ejemplo:


#include <stdio.h>
#define SIZE 20
int main(){
    char cad[SIZE];
    printf("Ingresar palabra: ");
    scanf("%s", cad);
    getchar();
    printf("%s\n", cad);
    fflush(stdin);
    printf("Ingresar oración: ");
    gets(cad);
    getchar();
    printf("%s\n", cad);
    fflush(stdin);
    return 0;
}

Ejemplo de salida:

Ingresar palabra: lee palabra
lee
warning: this program uses gets(), which is unsafe.
Ingresar oración: lee oración
lee oración

Como se puede observar en la salida anterior, scanf lee sólo una palabra; sin embargo, de no haberse limpiado el buffer, la palabra 'palabra' se habría quedado y la función gets la habría leído. A veces scanf o gets no logra detener la ejecución del programa; para ello, se puede ayudar con un getchar(); por eso se agrega después de la lectura de datos.

Arreglo bidimensional

Un arreglo bidimensional se almacena en la memoria de manera similar (de forma contigua); para ello, se requiere definir dos dimensiones (con dos corchetes) y manejar dos índices (para acceder a cada posición de la matriz en la posición renglón-columna).

Para definir una matriz, una opción es definir entre llaves cada uno de los renglones separados por coma. A continuación, se muestra cómo definir una matriz de cuatro renglones y tres columnas:

short nums[4][3] = {{99, 88, 77}, {66, 55, 44}, {33, 22, 11}, {999, 555, 111}};

Para acceder a un elemento en una matriz bidimensional nums se requiere dar la posición renglón-columna, es decir, nums[renglón][columna]. Al igual que con los arreglos unidimensionales, el índice de cada renglón o columna inicia en 0 y termina en N-1.

La siguiente imagen muestra una representación en memoria de un arreglo bidimensional.

Representación en memoria de un arreglo bidimensional

A continuación, se muestra un programa en lenguaje C que imprime las direcciones de memoria de los elementos en una matriz bidimensional:


#include<stdio.h>
int main(){
    short renglon, columna;
    short nums[4][3] = {{99,88,77},{66,55,44},{33,22,11},{999,555,111}};
    printf("Arreglo bidimensional\n");
    // Se iteran renglones y columnas
    for (renglon = 0; renglon < 4 ; renglon++){
        for (columna = 0; columna < 3 ; columna++){
            // Se imprime la dirección de memoria en hexadecimal
            printf("%p\t", &nums[renglon][columna]);
        }
        printf("\n");
    }
    return 0;
}

Ejemplo de salida:

Arreglo bidimensional
0x7ff7b2a79020  0x7ff7b2a79022  0x7ff7b2a79024
0x7ff7b2a79026  0x7ff7b2a79028  0x7ff7b2a7902a
0x7ff7b2a7902c  0x7ff7b2a7902e  0x7ff7b2a79030
0x7ff7b2a79032  0x7ff7b2a79034  0x7ff7b2a79036

Arreglo multidimensional

Para definir arreglos multidimensionales se debe seguir la siguiente lógica: cada dimensión está definida por un par de corchetes de apertura y cierre; así, si se tienen dos pares de corchetes se está definiendo el arreglo bidimensional; si se tienen tres pares de corchetes se está definiendo un arreglo tridimensional y así sucesivamente. La siguiente imagen muestra una representación en memoria de un arreglo tridimensional.

Representación en memoria de un arreglo tridimensional

Código de un arreglo tridimensional:


#include<stdio.h>
#define P 4
#define R 3
#define C 2
int main(){
    short plano, renglon, columna;
    float nums[P][R][C];
    printf("Arreglo tridimensional\n");
    for (plano = 0; plano < P; plano++){
        printf("Plano %d\n", plano+1);
        for (renglon = 0; renglon < R; renglon++){
            for (columna = 0; columna < C; columna++){
                printf("%p\t", &nums[renglon][columna]);
            }
            printf("\n");
        }
        printf("\n");
    }
    return 0;
}

Ejemplo de salida:

Arreglo tridimensional
Plano 1
0x7ff7bc752fd0  0x7ff7bc752fd8
0x7ff7bc752fe8  0x7ff7bc752ff0
0x7ff7bc753000  0x7ff7bc753008

Plano 2
0x7ff7bc752fd0  0x7ff7bc752fd8
0x7ff7bc752fe8  0x7ff7bc752ff0
0x7ff7bc753000  0x7ff7bc753008

Plano 3
0x7ff7bc752fd0  0x7ff7bc752fd8
0x7ff7bc752fe8  0x7ff7bc752ff0
0x7ff7bc753000  0x7ff7bc753008

Plano 4
0x7ff7bc752fd0  0x7ff7bc752fd8
0x7ff7bc752fe8  0x7ff7bc752ff0
0x7ff7bc753000  0x7ff7bc753008

Ejemplo: Suma de matrices

Las operaciones matriciales son muy comunes en las carreras STEM. Calcular la transpuesta, la matriz identidad, la suma o multiplicación de matrices, son algunos temas básicos durante la carrera. A continuación, ejemplificamos una suma de matrices en lenguaje C.

Contexto: Se realizará la suma de matrices A+B de 3x3. Los valores de las matrices están almacenados en dos archivos de texto, a.txt y b.txt, respectivamente. La lectura de las matrices, la suma y la impresión del resultado se realizarán en tres funciones distintas a main. En la función principal sólo se declararán las matrices y se llamará a las funciones respectivas.

Contenido del archivo a.txt:

10 20 30
40 50 60
70 80 90

Contenido del archivo b.txt:

90 80 70
60 50 40
30 20 10

Programa:


#include <stdio.h>
#define SIZE 3
enum boolean {False, True};
enum boolean leer_datos(int M[SIZE][SIZE], char nombre[20]);
void sumar_matrices(int A[SIZE][SIZE], int B[SIZE][SIZE], int C[SIZE][SIZE]);
void imprimir_matriz(int M[SIZE][SIZE]);
int main(){
    int A[SIZE][SIZE], B[SIZE][SIZE], C[SIZE][SIZE];
    if (!leer_datos(A, "a.txt")) {
        printf("No se pudo leer el archivo a.txt\n");
        return 1;
    }
    if (!leer_datos(B, "b.txt")) {
        printf("No se pudo leer el archivo b.txt\n");
        return 1;
    }
    sumar_matrices(A, B, C);
    imprimir_matriz(C);
    return 0;
}
enum boolean leer_datos(int M[SIZE][SIZE], char nombre[20]){
    FILE *f = fopen(nombre, "r");
    if (f==NULL) return False;
    short r, c;
    for (r=0; r<SIZE; r++)
        for (c=0; c<SIZE; c++)
            fscanf(f, "%d", &M[r][c]);
    return True;
}
void sumar_matrices(int A[SIZE][SIZE], int B[SIZE][SIZE], int C[SIZE][SIZE]){
    short r, c;
    for (r=0; r<SIZE; r++)
        for (c=0; c<SIZE; c++)
            C[r][c] = A[r][c] + B[r][c];
}
void imprimir_matriz(int M[SIZE][SIZE]){
    short r, c;
    for (r=0; r<SIZE; r++){
        for (c=0; c<SIZE; c++) {
            printf("%d\t", M[r][c]);
        }
        printf("\n");
    }
}

Ejemplo de salida:

100     100     100
100     100     100
100     100     100

Actividad 1. Multiplicación de matrices

En el siguiente programa en lenguaje C, el cual calcula la suma de los elementos de un arreglo, hay un detalle que está mal. Si se ejecuta así el programa va a fallar. Con lo que has aprendido, identifica en qué línea de código y en qué parte de la lógica está el error.

Actividad 2. Completa el código

Un programador debe escribir un programa en lenguaje C que calcule el producto escalar (producto punto) de dos vectores de R^N (N dimensiones, o tamaño N).

Actividad 3. Encuentra el error y arregla el programa

El siguiente programa en lenguaje C intenta calcular la transpuesta de una matriz; sin embargo, hay una línea que está incorrecta y que impide el funcionamiento correcto del programa.

Autoevaluación. Los arreglos

En esta autoevaluación podrás comprobar tus conocimientos teóricos acerca del tema de arreglos.

Fuentes de información

  • Ceballos, F. J. (1997). Enciclopedia del lenguaje C. Alfaomega.
  • Cormen, T. H., Leiserson, C. E., Rivest, R. L. & Stein, C. (2022). Introduction to algorithms. MIT Press.
  • Kernighan, B. W. y Ritchie, D. M. (1991). El lenguaje de programación C (2.ª ed.). Pearson Educación.

Cómo citar

Solano, J. A. (2026). Arreglos. Unidades de Apoyo para el Aprendizaje. Coordinación de Universidad Abierta y Educación Digital / Facultad de Ingeniería, Universidad Nacional Autónoma de México. (Vínculo)