vectores una punteros puntero por paso pasar parametros matriz llenar funciones funcion estructuras con como bidimensionales bidimensional arreglos arreglo c arrays

una - pasar punteros a funciones en c



Pasar una matriz como argumento a una funciĆ³n en C (8)

Al pasar una matriz como parámetro, esto

void arraytest(int a[])

significa exactamente lo mismo que

void arraytest(int *a)

entonces estás modificando los valores en main.

Por razones históricas, las matrices no son ciudadanos de primera clase y no pueden pasarse por valor.

Escribí una función que contiene una matriz como argumento, y la llamo pasando el valor de la matriz de la siguiente manera.

void arraytest(int a[]) { // changed the array a a[0]=a[0]+a[1]; a[1]=a[0]-a[1]; a[0]=a[0]-a[1]; } void main() { int arr[]={1,2}; printf("%d /t %d",arr[0],arr[1]); arraytest(arr); printf("/n After calling fun arr contains: %d/t %d",arr[0],arr[1]); }

Lo que encontré es que aunque estoy llamando a la función arraytest() pasando valores, se cambia la copia original de int arr[] .

¿Puedes explicar por qué?


En C, excepto en algunos casos especiales, una referencia de matriz siempre "decae" en un puntero al primer elemento de la matriz. Por lo tanto, no es posible pasar una matriz "por valor". Una matriz en una llamada de función se pasará a la función como un puntero, que es análogo a pasar la matriz por referencia.

EDITAR: hay tres casos especiales en los que una matriz no se descompone en un puntero a su primer elemento:

  1. sizeof a no es lo mismo que sizeof (&a[0]) .
  2. &a no es lo mismo que &(&a[0]) (y no es lo mismo que &a[0] ).
  3. char b[] = "foo" no es lo mismo que char b[] = &("foo") .

Está pasando el valor de la ubicación de memoria del primer miembro de la matriz.

Por lo tanto, cuando empiece a modificar la matriz dentro de la función, estará modificando la matriz original.

Recuerde que a[1] es *(a+1) .


Estás pasando la dirección del primer elemento de la matriz


Las matrices en C se convierten, en la mayoría de los casos, en un puntero al primer elemento de la matriz. Y más en detalle las matrices pasadas a funciones siempre se convierten en punteros.

Aquí una cita de K&R2nd :

Cuando se pasa un nombre de matriz a una función, lo que se pasa es la ubicación del elemento inicial. Dentro de la función llamada, este argumento es una variable local, por lo que un parámetro de nombre de matriz es un puntero, es decir, una variable que contiene una dirección.

Escritura:

void arraytest(int a[])

tiene el mismo significado que escribir:

void arraytest(int *a)

Entonces, a pesar de que no lo está escribiendo explícitamente, es como está pasando un puntero y por lo tanto está modificando los valores en el principal.

Para más, realmente sugiero leer this .

Además, puedes encontrar otras respuestas en SO here


No está pasando la matriz como copia. Es solo un puntero que apunta a la dirección donde está el primer elemento en la memoria.


Si desea pasar una matriz de dimensión única como argumento en una función , debería declarar un parámetro formal en una de las tres formas siguientes y los tres métodos de declaración producen resultados similares porque cada uno le dice al compilador que un puntero entero va para ser recibido

int func(int arr[], ...){ . . . } int func(int arr[SIZE], ...){ . . . } int func(int* arr, ...){ . . . }

Entonces, estás modificando los valores originales.

Gracias !!!


Pasar una matriz multidimensional como argumento a una función. Pasar una matriz tenue como argumento es más o menos trivial. Echemos un vistazo al caso más interesante de pasar una matriz de 2 dim. En C, no puede usar un puntero a construcción de puntero (int **) en lugar de 2 dim array. Hagamos un ejemplo:

void assignZeros(int(*arr)[5], const int rows) { for (int i = 0; i < rows; i++) { for (int j = 0; j < 5; j++) { *(*(arr + i) + j) = 0; // or equivalent assignment arr[i][j] = 0; } }

Aquí he especificado una función que toma como primer argumento un puntero a una matriz de 5 ints. Puedo pasar como argumento cualquier 2 matriz oscura que tenga 5 columnas:

int arr1[1][5] int arr1[2][5] ... int arr1[20][5] ...

Puede llegar a una idea para definir una función más general que pueda aceptar cualquier matriz 2 dim y cambiar la firma de la función de la siguiente manera:

void assignZeros(int ** arr, const int rows, const int cols) { for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { *(*(arr + i) + j) = 0; } } }

Este código se compilará pero obtendrá un error de tiempo de ejecución al intentar asignar los valores de la misma manera que en la primera función. Entonces, en C, las matrices multidimensionales no son lo mismo que los punteros a los punteros ... a los punteros. Un int (* arr) [5] es un puntero a una matriz de 5 elementos, un int (* arr) [6] es un puntero a una matriz de 6 elementos, ¡y son punteros a diferentes tipos!

Bueno, ¿cómo definir argumentos de funciones para dimensiones más altas? Simple, ¡solo seguimos el patrón! Hier es la misma función ajustada para tomar una matriz de 3 dimensiones:

void assignZeros2(int(*arr)[4][5], const int dim1, const int dim2, const int dim3) { for (int i = 0; i < dim1; i++) { for (int j = 0; j < dim2; j++) { for (int k = 0; k < dim3; k++) { *(*(*(arr + i) + j) + k) = 0; // or equivalent assignment arr[i][j][k] = 0; } } } }

Como es de esperar, puede tomar como argumento 3 arreglos tenues que tengan en las segundas dimensiones 4 elementos y en la tercera dimensión 5 elementos. Cualquier cosa como esta estaría bien:

arr[1][4][5] arr[2][4][5] ... arr[10][4][5] ...

Pero tenemos que especificar todos los tamaños de dimensiones hasta el primero.