En el lenguaje C, los argumentos en las funciones siempre se pasan por valor. Esto significa que la función recibe una copia del valor del argumento. Para tipos simples (int, float) esto es obvio: los cambios dentro de la función no afectan a la variable original. Para arrays y estructuras hay matices:
Ejemplo: manejo de un array y una estructura
#include <stdio.h> typedef struct { int a; int b; } Par; void modificarArray(int arr[], int tamaño) { arr[0] = 42; // modifica el array original } void modificarStruct(Par s) { s.a = 100; // solo cambia la copia local } void modificarStructPtr(Par *s) { s->a = 200; // cambia el original a través del puntero } int main() { int nums[2] = {1, 2}; Par p = {10, 20}; modificarArray(nums, 2); modificarStruct(p); modificarStructPtr(&p); printf("nums[0]=%d, p.a=%d\n", nums[0], p.a); // nums[0]=42, p.a=200 return 0; }
Pregunta: Si la función se declara como void func(int arr[10]), ¿siempre tendrá ese array dentro de la función 10 elementos?
Respuesta: No. La declaración int arr[10] en los argumentos es en realidad equivalente a int *arr — el tamaño del array se pierde al pasar. La función no conoce la longitud real del array, por lo que siempre se debe pasar un parámetro adicional con su longitud. De lo contrario, pueden ocurrir salidas fuera de los límites del array y UB.
Ejemplo:
void foo(int arr[10]) { printf("%d\n", arr[9]); // arr no necesariamente contiene 10 elementos! }
Historia
En un proyecto de procesamiento de señales se pasó un array a través de una función, esperando que su longitud fuera siempre la misma, pero en un caso se pasó un array más pequeño. El resultado fue un acceso fuera de los límites de la memoria, caída de la aplicación y aparición de comportamientos impredecibles en el controlador.
Historia
En un software bancario se intentó modificar una estructura pasándola por valor, en lugar de por puntero. Los cambios no se guardaron, lo que provocó que el módulo de procesamiento no actualizara el estado de las cuentas, resultando en errores en los cálculos.
Historia
En un sistema de telemetría, un estudiante agregó una función para limpiar un array, pero olvidó pasar la longitud, y los arrays eran de diferente tamaño. El error se detectó solo después de recopilar un gran volumen de datos incorrectos y un largo tiempo de búsqueda de errores.