ProgramaciónProgramador de sistemas

¿Puede explicar en detalle los mecanismos de paso de parámetros en funciones del lenguaje C: por valor y por puntero? Proporcione ejemplos en los que el uso de cada enfoque esté justificado.

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

En el lenguaje C, los parámetros en las funciones siempre se pasan por valor — es decir, se pasa una copia del valor desde el código que llama a la función. Si se necesita cambiar el valor de una variable fuera de la función, se utiliza el paso por puntero.

Paso por valor

Al pasar un escalar (por ejemplo, int), la función recibe su copia:

void foo(int a) { a = 10; } int main() { int x = 5; foo(x); // x == 5, ¡no cambiará! }

Paso por puntero

Para cambiar el valor de una variable, se utiliza un puntero:

void foo(int* a) { *a = 10; } int main() { int x = 5; foo(&x); // x == 10, ¡el valor ha cambiado! }

Cuándo usar punteros

  • Necesita devolver varios valores.
  • Cambiar estructuras grandes (ahorro de tiempo y memoria, sin copiado).
  • Para trabajar con matrices (siempre se pasan como puntero).

Pregunta engañosa.

¿Es una matriz un parámetro de función pasado por referencia?

Muchos responden que "por referencia", sin embargo, en C, una matriz en la firma de la función no puede ser pasada por referencia, en realidad, se degrada a un puntero.

Respuesta correcta:

Cuando una matriz se pasa a una función, en realidad se pasa un puntero a su primer elemento. Es decir, la función llamada no conoce el tamaño real de la matriz, y cualquier cambio en los elementos de la matriz se refleja en la matriz original.

void foo(int arr[]) { arr[0] = 100; } int main() { int a[3] = {1,2,3}; foo(a); // a[0] será 100! }

Historia


En un proyecto, una función actualizaba los valores de una matriz, declarada como int arr[10], pero en el código que llama, la matriz era de menor tamaño. Debido a que la función no conocía el tamaño real, ocurrió un desbordamiento de búfer y se dañó la memoria.


En otro caso, debido al paso de una estructura por valor a una función, se copió un gran bloque de memoria varias veces, lo que causó una caída en el rendimiento de la aplicación.


El desarrollador esperaba que el paso de un escalar "por referencia" (a través de un puntero) garantizara que el valor original no cambiaría, pero por error modificó en un puntero la memoria fuera del ámbito visible (error en la aritmética de punteros), lo que llevó a resultados impredecibles.