Paso de arreglos en funciones.

 

Pasar arreglos como parámetros en C++

En C++, existen dos formas principales de pasar arreglos como parámetros a las funciones: por valor y por referencia. La forma en que se pasa el arreglo determina cómo se comporta el arreglo dentro de la función y cómo afecta al arreglo original.

El paso predefinido de un arreglo como parámetro de una función es por referencia.

Paso por valor:

  • No existe el paso de un arreglo por valor. Pero podemos emularlo anteponiendo la palabra reservada const.
  • De esta forma cualquier modificación realizada al arreglo dentro de la función marcará un error.
  • Este método es útil cuando no se desea que la función modifique el arreglo original o cuando se trabaja con arreglos pequeños.

Ejemplo:

C++
void imprimirArreglo(const int arr[], int tam) {
  for (int i = 0; i < tam; i++) {
    std::cout << arr[i] << " ";
  }
  std::cout << std::endl;
}

int main() {
  int arreglo[] = {1, 2, 3, 4, 5};
  imprimirArreglo(arreglo, 5); // Se pasa una copia del arreglo
  arreglo[2] = 10; // Se modifica el arreglo original
  imprimirArreglo(arreglo, 5); // Se imprime el arreglo original modificado
  return 0;
}

Paso por referencia:

  • Cuando se pasa un arreglo por referencia, se pasa la dirección de memoria del arreglo original a la función.
  • Cualquier modificación realizada en el arreglo dentro de la función afecta directamente al arreglo original.
  • Este método es útil cuando se necesita que la función modifique el arreglo original o cuando se trabaja con arreglos grandes para evitar la copia.

Ejemplo:

C++
void modificarArreglo(int arr[], int tam) {
  for (int i = 0; i < tam; i++) {
    arr[i] *= 2;
  }
}

int main() {
  int arreglo[] = {1, 2, 3, 4, 5};
  imprimirArreglo(arreglo, 5); // Se pasa la referencia al arreglo
  modificarArreglo(arreglo, 5); // Se modifica el arreglo original
  imprimirArreglo(arreglo, 5); // Se imprime el arreglo original modificado
  return 0;
}

Vectores:

Los vectores en C++ se pasan por referencia por defecto. Esto significa que cualquier modificación realizada en el vector dentro de la función afecta directamente al vector original.

Ejemplo:

C++
#include <vector>

void modificarVector(std::vector<int>& vector) {
  vector.push_back(10);
}

int main() {
  std::vector<int> vector = {1, 2, 3, 4, 5};
  imprimirVector(vector); // Se pasa la referencia al vector
  modificarVector(vector); // Se modifica el vector original
  imprimirVector(vector); // Se imprime el vector original modificado
  return 0;
}

Pasando Matrices con Punteros en C++

Entendiendo la mecánica:

Cuando hablamos de pasar una matriz como parámetro a una función en C++, en realidad lo que estamos pasando es un puntero al primer elemento de esa matriz. Esto significa que dentro de la función, cualquier modificación que hagamos a los elementos de la matriz se verá reflejada en la matriz original.

¿Por qué usar punteros?

  • Flexibilidad: Nos permite trabajar con matrices de diferentes tamaños sin tener que especificar las dimensiones exactas en la declaración de la función.
  • Eficiencia: Evita la creación de copias innecesarias de la matriz, lo que puede ser costoso en términos de tiempo y memoria.

Ejemplo:

C++
#include <iostream>

void imprimirMatriz(int *matriz, int filas, int columnas) {
    for (int i = 0; i < filas; i++) {
        for (int j = 0; j < columnas; j++) {
            std::cout << *(matriz + i * columnas + j) << " ";
        }
        std::cout << std::endl;
    }
}

int main() {
    int miMatriz[2][3] = {{1, 2, 3}, {4, 5, 6}};
    imprimirMatriz((int*)miMatriz, 2, 3);
    return 0;
}

Explicación:

  1. Declaración de la función:
    • int *matriz: Se declara un puntero a un entero, que apuntará al primer elemento de la matriz.
    • int filas, int columnas: Se pasan las dimensiones de la matriz como parámetros adicionales.
  2. Acceso a los elementos:
    • *(matriz + i * columnas + j): Se utiliza aritmética de punteros para acceder a cada elemento de la matriz. La expresión i * columnas + j calcula el desplazamiento desde el principio de la matriz hasta el elemento en la fila i y columna j.
  3. Llamada a la función:
    • (int*)miMatriz: Se realiza un cast a int* para convertir el nombre de la matriz en un puntero al primer elemento.

Ventajas de usar punteros:

  • Mayor control: Puedes realizar operaciones más complejas con las matrices, como cambiar su tamaño o pasar porciones de la matriz a otras funciones.
  • Generalidad: Puedes trabajar con matrices de diferentes tipos de datos.

Consideraciones importantes:

  • Dimensiones: Siempre es necesario pasar las dimensiones de la matriz como parámetros adicionales, ya que el compilador no puede inferirlas automáticamente a partir del puntero.
  • Cuidado con los límites: Asegúrate de no acceder a elementos fuera de los límites de la matriz, ya que esto puede causar un comportamiento indefinido.
  • Matrices multidimensionales: Para matrices multidimensionales, puedes utilizar punteros dobles o plantillas para lograr una mayor flexibilidad.

En resumen:

  • El paso por valor se utiliza cuando no se desea que la función modifique el arreglo original o cuando se trabaja con arreglos pequeños.
  • El paso por referencia se utiliza cuando se necesita que la función modifique el arreglo original o cuando se trabaja con arreglos grandes.
  • Los vectores en C++ se pasan por referencia por defecto.
  • Pasar una matriz como puntero te brinda un mayor control y flexibilidad al trabajar con matrices en C++. Sin embargo, requiere un manejo cuidadoso de la aritmética de punteros y de las dimensiones de la matriz.



Comentarios

Entradas más populares de este blog

Generación de números aleatorios

Paso de parámetros en funciones

STL de C++