ProgramaciónDesarrollador C

¿Cómo funciona el mecanismo de transmisión de argumentos en las funciones del lenguaje C? ¿Cómo evitar errores de tipo al pasar variables de diferentes tipos, estructuras y arrays?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

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:

  • Al pasar un array a una función, de hecho se pasa un puntero a su primer elemento, no todo el array. Sin embargo, el puntero en sí se pasa por valor.
  • Para estructuras se puede pasar explícitamente una copia (por valor), pero es más beneficioso hacer esta copia a través de un puntero, de modo que la función pueda modificar la estructura original.

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 con trampa.

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.