ProgramaciónDesarrollador C

¿En qué se diferencian los punteros y los arreglos en el lenguaje C? ¿Cómo se pasa correctamente un arreglo a una función?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

Los punteros y los arreglos en C están relacionados, pero no son lo mismo:

  • Arreglo — conjunto de elementos del mismo tipo en la memoria, definido por un tamaño.
  • Puntero — variable que almacena una dirección en la memoria, donde puede apuntar un arreglo o un objeto individual.

Al pasar un arreglo a una función, de hecho se pasa un puntero al primer elemento del arreglo (por lo que sizeof dentro de la función no da el tamaño de todo el arreglo, sino solo el tamaño del puntero).

Sintaxis para pasar:

void foo(int arr[], int size) { // arr — de hecho int* for (int i = 0; i < size; ++i) printf("%d\n", arr[i]); } int main() { int data[5] = {1,2,3,4,5}; foo(data, 5); }

Pregunta tricky.

Pregunta: ¿Qué devolverá la expresión sizeof(arr) dentro de la función, si arr es un parámetro de tipo int arr[]?

Respuesta: Devuelve el tamaño del puntero (sizeof(int*)), y no el tamaño de todo el arreglo. Porque se pasa a la función un puntero al primer elemento, la información sobre la longitud se pierde.

Ejemplo de código:

void printSize(int arr[]) { printf("%zu\n", sizeof(arr)); // sizeof(int*) generalmente 4 u 8 }

Historia

En un proyecto comercial se escribió un código para calcular el promedio de un arreglo, donde se tomaba sizeof(arr) / sizeof(arr[0]) para el número de elementos dentro de la función, lo que siempre devolvía 1 o 2 en lugar de la verdadera cantidad de elementos. Debido a esto, el programa funcionaba incorrectamente con los datos, promediando valores incorrectamente.


Historia

En un proyecto, un arreglo dinámicamente asignado se pasó a una función sin almacenar por separado la longitud (size). Como resultado, la función no sabía cuántos elementos se habían asignado, lo que llevaba a desbordamientos, pérdidas o corrupción de memoria.


Historia

Por error, se utilizó un arreglo de tamaño fijo como puntero, y en algunos compiladores se permitía la asignación directa a través de memcpy de todo el arreglo en lugar de sus elementos. Esto llevó a errores no evidentes, donde se perdían partes de la estructura de datos o ocurría un desbordamiento de pila.