una referencia recibir recibe que por pasar parametro matriz matrices llenar funciones funcion con bidimensionales arreglos c arrays function parameter-passing space-efficiency

recibir - pasar una matriz por referencia en c



Diferencia entre pasar matriz y puntero de matriz en funciĆ³n en C (3)

¿Cuál es la diferencia entre las dos funciones en C?

void f1(double a[]) { //... } void f2(double *a) { //... }

Si tuviera que llamar a las funciones en una matriz sustancialmente larga, ¿estas dos funciones se comportarían de manera diferente, tomarían más espacio en la pila?


La diferencia es puramente sintáctica. En C, cuando la notación de matriz se usa para un parámetro de función, se transforma automáticamente en una declaración de puntero.


No, no hay diferencia entre ellos. Para probar, escribí este código C en el compilador Dev C ++ (mingw):

#include <stdio.h> void function(int* array) { int a =5; } void main() { int array[]={2,4}; function(array); getch(); }

Cuando desensamblo la función principal en .exe de ambas versiones de llamada del archivo binario en IDA, obtengo exactamente el mismo código de ensamblado que se muestra a continuación:

push ebp mov ebp, esp sub esp, 18h and esp, 0FFFFFFF0h mov eax, 0 add eax, 0Fh add eax, 0Fh shr eax, 4 shl eax, 4 mov [ebp+var_C], eax mov eax, [ebp+var_C] call sub_401730 call sub_4013D0 mov [ebp+var_8], 2 mov [ebp+var_4], 4 lea eax, [ebp+var_8] mov [esp+18h+var_18], eax call sub_401290 call _getch leave retn

Entonces no hay diferencia entre las dos versiones de esta llamada, al menos el compilador las amenaza por igual.


Primero, algunos standardese :

6.7.5.3 Declaradores de función (incluidos prototipos)
...
7 Una declaración de un parámetro como "matriz de tipo " se ajustará a "puntero calificado para escribir ", donde los calificadores de tipo (si los hay) son los especificados dentro de [ y ] de la derivación de tipo de matriz. Si la palabra clave static también aparece dentro de [ y ] de la derivación del tipo de matriz, entonces para cada llamada a la función, el valor del argumento real correspondiente proporcionará acceso al primer elemento de una matriz con al menos tantos elementos como se especifique por la expresión de tamaño.

Entonces, en resumen, cualquier parámetro de función declarado como T a[] o T a[N] se trata como si se hubiera declarado T *a .

Entonces, ¿por qué se tratan los parámetros de matriz como si hubieran sido declarados como punteros? Este es el por qué:

6.3.2.1 Valores L, matrices y designadores de funciones
...
3 Excepto cuando es el operando del operador sizeof o unary & operator, o es un literal de cadena usado para inicializar una matriz, una expresión que tiene el tipo '''' array of type '''' se convierte en una expresión con el tipo '''' pointer escribir '''' que apunta al elemento inicial del objeto array y no es un valor l. Si el objeto de matriz tiene una clase de almacenamiento de registro, el comportamiento no está definido.

Dado el siguiente código:

int main(void) { int arr[10]; foo(arr); ... }

En la llamada a foo , la expresión de matriz arr no es un operando de sizeof o & , por lo que su tipo se convierte implícitamente de "matriz de 10 elementos de int " a "puntero a int " de acuerdo con 6.2.3.1/3. Por lo tanto, foo recibirá un valor de puntero, en lugar de un valor de matriz.

Debido a 6.7.5.3/7, puedes escribir foo como

void foo(int a[]) // or int a[10] { ... }

pero será interpretado como

void foo(int *a) { ... }

Por lo tanto, las dos formas son idénticas.

La última oración en 6.7.5.3/7 se introdujo con C99, y básicamente significa que si tiene una declaración de parámetro como

void foo(int a[static 10]) { ... }

el parámetro real correspondiente a a debe ser una matriz con al menos 10 elementos.