Transmiterea matricelor multidimensionale ca argumente funcționale în C

În C, pot trece o matrice multidimensională unei funcții ca un singur argument atunci când nu știu care vor fi dimensiunile matricei?

În plus, matricea mea multidimensională poate conține alte tipuri decât șiruri de caractere.

0
fr hi bn

4 răspunsuri

Puteți face acest lucru cu orice tip de date. Pur și simplu face-o un pointer-la-pointer:

typedef struct {
  int myint;
  char* mystring;
} data;

data** array;

Dar nu uitați că încă trebuie să malloc variabila, și se face un pic mai complex:

//initialize
int x,y,w,h;
w = 10; //width of array
h = 20; //height of array

//malloc the 'y' dimension
array = malloc(sizeof(data*) * h);

//iterate over 'y' dimension
for(y=0;y

Codul de alocare a structurii arată similar - nu uitați să sunați gratuit() pe tot ce ați mallocat! (De asemenea, în aplicații robuste, trebuie să să verificați returnarea malloc() .)

Acum, să presupunem că doriți să transmiteți această funcție unei funcții. Puteți utiliza în continuare pointerul dublu, deoarece probabil că doriți să faceți manipulări pe structura de date, nu pe pointer la indicii structurilor de date:

int whatsMyInt(data** arrayPtr, int x, int y){
  return arrayPtr[y][x].myint;
}

Apelați această funcție cu:

printf("My int is %d.\n", whatsMyInt(array, 2, 4));

ieşire:

My int is 6.
0
adăugat
Un pointer pentru a afișa tabela de căutare segmentată nu este o matrice 2D. Doar pentru că permite sintaxa [] [] , ea nu se transformă în magie într-o matrice. Nu puteți memcpy() etc deoarece memoria nu este alocată în celulele de memorie adiacente, ceea ce este necesar pentru arrays. Tabelul dvs. de căutare este destul de împrăștiat peste tot heap, făcând cautările să fie lent și halda fragmentată.
adăugat autor Lundin, sursa
adăugat autor Dchris, sursa

Treceți un pointer explicit la primul element cu dimensiunile matricei ca parametri separați. De exemplu, pentru a manipula matrice arbitrar de 2-d de int:

void func_2d(int *p, size_t M, size_t N)
{
  size_t i, j;
  ...
  p[i*N+j] = ...;
}

care ar fi numit ca

...
int arr1[10][20];
int arr2[5][80];
...
func_2d(&arr1[0][0], 10, 20);
func_2d(&arr2[0][0], 5, 80);

Același principiu se aplică și pentru rețelele cu dimensiuni mai mari:

func_3d(int *p, size_t X, size_t Y, size_t Z)
{
  size_t i, j, k;
  ...
  p[i*Y*Z+j*Z+k] = ...;
  ...
}
...
arr2[10][20][30];
...
func_3d(&arr[0][0][0], 10, 20, 30);
0
adăugat
Care sunt valorile lui i și j?
adăugat autor Akshay Immanuel D, sursa
adăugat autor Dchris, sursa

Y * Z + j ar trebui să fie .

adăugat autor David H, sursa

Vă puteți declara funcția ca:

f(int size, int data[][size]) {...}

Compilatorul va face apoi toate aritmetica pointer pentru tine.

Rețineți că dimensiunile dimensiunilor trebuie să apară înainte de matricea însăși.

GNU C permite redirecționarea declarației argumentului (în cazul în care într-adevăr trebuie să treceți dimensiunile după matrice):

f(int size; int data[][size], int size) {...}

Prima dimensiune, deși puteți trece și ca argument, este inutilă pentru compilatorul C (chiar și pentru operatorul sizeof, atunci când este aplicat peste matrice trecut ca argument va trata întotdeauna este ca un pointer la primul element).

0
adăugat
OMI ar trebui să fie răspunsul acceptat. Nu este necesar un cod suplimentar și nu există alocări de heap inutile. simplu și curat
adăugat autor imkendal, sursa
Eu declar funcția așa cum ați spus, o numesc de la main() și este ok, dar cum ar trebui să declar variabila data în principal() dacă nu cunosc dimensiunea (dimensiunile)? Am încercat cu int * data , dar nu va funcționa.
adăugat autor Glk-78, sursa
Multumesc @ kjh, de asemenea, cred că aceasta este cea mai curată soluție. Răspunsul acceptat este cel care a lucrat pentru el. Uită-te: PO este din 2008, cu aproape 6 ani înainte de răspunsul meu. În afară de asta, nu știu dacă în acel moment s-au permis standardele C pentru sintaxa pe care am folosit-o aici.
adăugat autor rslemos, sursa
Aceasta este soluția pe care am adoptat-o ​​pentru trecerea unei matrice întregi (o matrice bidimensională) de dimensiune M x N ca argument al funcției. Poate că vor fi utile mai multe informații: Prototipul funcției este similar cu: void f (int N, int date [] [N], int M); În corpul funcției, elementul [m] [n] poate fi scris ca date [m] [n] - foarte convenabil, nu este necesară calculul indexului.
adăugat autor jonathanzh, sursa
int matmax(int **p, int dim) // p- matrix , dim- dimension of the matrix 
{
    return p[0][0];  
}

int main()
{
   int *u[5]; // will be a 5x5 matrix

   for(int i = 0; i < 5; i++)
       u[i] = new int[5];

   u[0][0] = 1; // initialize u[0][0] - not mandatory

   // put data in u[][]

   printf("%d", matmax(u, 0)); //call to function
   getche(); // just to see the result
}
0
adăugat
Aceasta nu este o matrice 2D, este o tabelă de căutare. De asemenea, aceasta este marcată cu C.
adăugat autor Lundin, sursa
adăugat autor Dchris, sursa