Multidimensionale arrays doorgeven als functieargumenten in C

In Ckan ik een multidimensionale array doorgevenaan een functie als een enkel argumentals ik niet weet wat de afmetingen van de array zal zijn?

Bovendien kan mijn multidimensionale array andere typen dan strings bevatten.


Antwoord 1, autoriteit 100%

Geef een expliciete aanwijzer door naar het eerste element met de arraydimensies als afzonderlijke parameters. Om bijvoorbeeld 2-d arrays van int van willekeurige grootte te verwerken:

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

die zou worden genoemd als

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

Hetzelfde principe is van toepassing op arrays met een hogere dimensie:

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);

Antwoord 2, autoriteit 67%

U kunt uw functie declareren als:

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

De compiler zal dan alle pointerberekeningen voor je doen.

Houd er rekening mee dat de afmetingen van de afmetingen vóórde array zelf moeten verschijnen.

GNU C maakt het doorsturen van argumentdeclaraties mogelijk (voor het geval je echt dimensies moet doorgeven na de array):

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

De eerste dimensie, hoewel je deze ook als argument kunt doorgeven, is nutteloos voor de C-compiler (zelfs voor sizeof-operator, wanneer toegepast over array die als argument wordt doorgegeven, wordt altijd behandeld als een verwijzing naar het eerste element).


Antwoord 3, autoriteit 64%

U kunt dit met elk gegevenstype doen. Maak er gewoon een pointer-to-pointer van:

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

Maar vergeet niet dat je de variabele nog steeds moet malloceren, en het wordt een beetje ingewikkeld:

//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<h;y++){
  //malloc the 'x' dimension
  array[y] = malloc(sizeof(data) * w);
  //iterate over the 'x' dimension
  for(x=0;x<w;x++){
    //malloc the string in the data structure
    array[y][x].mystring = malloc(50); //50 chars
    //initialize
    array[y][x].myint = 6;
    strcpy(array[y][x].mystring, "w00t");
  }
}

De code om de toewijzing van de structuur ongedaan te maken lijkt op elkaar – vergeet niet om free() aan te roepen voor alles wat je hebt gemalloceerd! (Bovendien moet u in robuuste toepassingen de terugkeer van malloc()controleren .)

Stel nu dat u dit aan een functie wilt doorgeven. Je kunt nog steeds de dubbele pointer gebruiken, omdat je waarschijnlijk manipulaties wilt doen op de datastructuur, niet de pointer naar pointers van datastructuren:

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

Roep deze functie aan met:

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

Uitvoer:

My int is 6.

Antwoord 4, autoriteit 3%

Kan ik in C een multidimensionale array doorgeven aan een functie als een enkel argument als ik niet weet wat de afmetingen van de array zullen zijn?

Nee

Als je met “enkel argument” bedoelt dat alleen de array wordt doorgegeven zonder de array-dimensies door te geven, nee, dat kan niet. Tenminste niet voor echte multidimensionale arrays.

Je kunt de dimensie[s] samen met de array in een structuur plaatsen en beweren dat je een “enkel argument” doorgeeft, maar dat is eigenlijk gewoon meerdere waarden in een enkele container stoppen en die container “één argument” noemen.

U kunt een array met een bekend type en aantal dimensies maar onbekende grootte doorgeven door de dimensies zelf en de array als volgt door te geven:

void print2dIntArray( size_t x, size_t y, int array[ x ][ y ] )
{
    for ( size_t ii = 0, ii < x; ii++ )
    {
        char *sep = "";
        for ( size_t jj = 0; jj < y; jj++ )
        {
            printf( "%s%d", sep, array[ ii ][ jj ] );
            sep = ", ";
        }
        printf( "\n" );
    }
}

Je zou die functie als volgt aanroepen:

int a[ 4 ][ 5 ];
int b[ 255 ][ 16 ];
...
print2dIntArray( 4, 5, a );
....
printt2dIntArray( 255, 16, b );

Evenzo een driedimensionale array van bijvoorbeeld een struct pixel:

void print3dPixelArray( size_t x, size_t y, size_t z, struct pixel pixelArray[ x ][ y ][ z ] )
{
    ...
}

of een 1-dimensionale doublearray:

void print1dDoubleArray( size_t x, double doubleArray[ x ] )
{
    ...
}

MAAR…

Het kan echter mogelijk zijn om “arrays van pointers naar arrays van pointers naar … een array van het type X” constructies door te geven die vaak verkeerd worden gelabeld als een “multidimensionale array” als een enkele argument zolang het basistype Xeen schildwachtwaarde heeft die kan worden gebruikt om het einde aan te geven van de laatste eendimensionale array op het laagste niveau van het type X.

Bijvoorbeeld, de char **argvwaarde die wordt doorgegeven aan main()is een pointer naar een array van pointers naar char. De initiële array van char *pointers eindigt met een NULLschildwachtwaarde, terwijl elke chararray waarnaar wordt verwezen door de array van char *-aanwijzers eindigen op een NULtekenwaarde van '\0'.

Als u bijvoorbeeld NANals schildwachtwaarde kunt gebruiken omdat de werkelijke gegevens nooiteen NANzullen zijn, kunt u afdrukken een double **zoals dit:

void printDoubles( double **notAnArray )
{
    while ( *notAnArray )
    {
        char *sep = "";
        for ( size_t ii = 0;  ( *notAnArray )[ ii ] != NAN; ii++ )
        {
            printf( "%s%f", sep, ( *notAnArray )[ ii ] );
            sep = ", ";
        }
        notAnArray++;
    }
}

Antwoord 5

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
}

Other episodes