Im C
kann ich Übergeben Sie ein mehrdimensionales Array zu einer Funktion als einziges Argument wenn ich nicht weiß, was die Dimensionen des Arrays sein werden?
Außerdem kann mein mehrdimensionales Array andere Typen als Strings enthalten.
David
Im C
kann ich Übergeben Sie ein mehrdimensionales Array zu einer Funktion als einziges Argument wenn ich nicht weiß, was die Dimensionen des Arrays sein werden?
Außerdem kann mein mehrdimensionales Array andere Typen als Strings enthalten.
Johannes Bode
Übergeben Sie einen expliziten Zeiger auf das erste Element mit den Array-Dimensionen als separate Parameter. Zum Beispiel, um beliebig große 2-D-Arrays von int zu verarbeiten:
void func_2d(int *p, size_t M, size_t N)
{
size_t i, j;
...
p[i*N+j] = ...;
}
was als bezeichnet werden würde
...
int arr1[10][20];
int arr2[5][80];
...
func_2d(&arr1[0][0], 10, 20);
func_2d(&arr2[0][0], 5, 80);
Dasselbe Prinzip gilt für höherdimensionale Arrays:
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);
p[i*Y+j*Z+k]
sollte sein p[i*Y*Z+j*Z+k]
stattdessen.
– David H
18. August 2012 um 9:01 Uhr
stackoverflow.com/questions/16943909/…
– Dchris
5. Juni 2013 um 16:02 Uhr
Was sind die Werte von i und j?
– AlphaGoku
6. April 2016 um 9:17 Uhr
Vielen Dank für deine Antwort, @John Bode. Könnten Sie bitte erklären, warum Sie das tun p[i*N+j]
um ein bestimmtes Element des mehrdimensionalen Arrays zu adressieren?
– F.Zer
12. Oktober 2021 um 16:52 Uhr
@F.Zer – Ja. In diesem Beispiel haben wir zwei Spalten pro Zeile.
– Johannes Bode
12. Oktober 2021 um 19:56 Uhr
rslemos
Sie können Ihre Funktion wie folgt deklarieren:
f(int size, int data[][size]) {...}
Der Compiler erledigt dann die gesamte Zeigerarithmetik für Sie.
Beachten Sie, dass die Bemaßungsgrößen erscheinen müssen Vor das Array selbst.
GNU C ermöglicht die Weiterleitung von Argumentdeklarationen (falls Sie wirklich Dimensionen nach dem Array übergeben müssen):
f(int size; int data[][size], int size) {...}
Obwohl Sie die erste Dimension auch als Argument übergeben können, ist sie für den C-Compiler nutzlos (selbst für den sizeof-Operator, wenn er auf ein als Argument übergebenes Array angewendet wird, wird es immer als Zeiger auf das erste Element behandelt).
IMO sollte dies die akzeptierte Antwort sein. Kein zusätzlicher Code erforderlich und keine unnötigen Heap-Zuweisungen. einfach und sauber
– kjh
27. April 2015 um 17:03 Uhr
Danke @kjh, ich denke auch, dass dies die sauberste Lösung ist. Die akzeptierte Antwort ist diejenige, die für ihn funktioniert hat. Schauen Sie: Das OP ist von 2008, fast 6 Jahre vor meiner Antwort. Abgesehen davon weiß ich nicht, ob die damaligen C-Standards die Syntax erlaubten, die ich hier verwendet habe.
– rslemos
30. April 2015 um 3:23 Uhr
Dies ist die Lösung, die ich schließlich angenommen habe, um eine ganzzahlige Matrix (ein zweidimensionales Array) der Größe M x N als Funktionsargument zu übergeben. Vielleicht sind ein paar mehr Informationen hilfreich: Der Funktionsprototyp ist wie folgt: void f(int N, int data[][N], int M); Im Hauptteil der Funktion element [m][n] können als Daten geschrieben werden[m][n] – sehr praktisch, es ist keine Indexberechnung erforderlich.
– jonathanzh
19. Mai 2015 um 9:08 Uhr
Ich deklariere die Funktion, wie Sie sagten, ich rufe sie von main () auf und es ist in Ordnung, aber wie soll ich die Variable deklarieren data
in meinem main(), wenn ich die Größe(n) nicht kenne? Ich habe es mit versucht int* data
aber wird nicht funktionieren.
– glc78
27. August 2017 um 11:30 Uhr
@glc78 Entweder als VLA auf dem Stack int data[height][width];
oder auf dem Haufen mit int (*data)[width] = malloc(height*sizeof(*data));
. In beiden Fällen können Sie anschließend zugreifen data[y][x]
auf die übliche Weise und übergeben Sie es an f(width, data)
.
– Cmaster – Wiedereinsetzung von Monica
13. Dezember 2019 um 9:13 Uhr
andrewrk
Sie können dies mit jedem Datentyp tun. Machen Sie es einfach zu einem Zeiger-zu-Zeiger:
typedef struct {
int myint;
char* mystring;
} data;
data** array;
Aber vergessen Sie nicht, dass Sie die Variable immer noch mallocieren müssen, und es wird ein bisschen komplex:
//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");
}
}
Der Code zum Freigeben der Struktur sieht ähnlich aus – vergessen Sie nicht, free() für alles aufzurufen, was Sie mallociert haben! (Auch in robusten Anwendungen sollten Sie Überprüfen Sie die Rückgabe von malloc().)
Nehmen wir nun an, Sie möchten dies an eine Funktion übergeben. Sie können immer noch den Doppelzeiger verwenden, da Sie wahrscheinlich Manipulationen an der Datenstruktur vornehmen möchten, nicht am Zeiger auf Zeiger von Datenstrukturen:
int whatsMyInt(data** arrayPtr, int x, int y){
return arrayPtr[y][x].myint;
}
Rufen Sie diese Funktion auf mit:
printf("My int is %d.\n", whatsMyInt(array, 2, 4));
Ausgabe:
My int is 6.
Hier wird Hilfe benötigt: stackoverflow.com/questions/16943909/…
– Dchris
5. Juni 2013 um 16:01 Uhr
Eine Zeiger-zu-Zeiger-segmentierte Nachschlagetabelle ist kein 2D-Array. Einfach weil es erlaubt ist [][]
Syntax, es verwandelt sich nicht auf magische Weise in ein Array. Sie können es nicht memcpy() usw. verwenden, da der Speicher nicht in benachbarten Speicherzellen zugewiesen wird, was für Arrays erforderlich ist. Ihre Nachschlagetabelle ist ziemlich über den ganzen Heap verstreut, was die Suche verlangsamt und den Heap fragmentiert.
– Ludin
23. Juni 2015 um 10:42 Uhr
Kann ich in C ein mehrdimensionales Array als einzelnes Argument an eine Funktion übergeben, wenn ich nicht weiß, welche Dimensionen das Array haben wird?
Nein
Wenn Sie mit “einzelnem Argument” meinen, nur das Array zu übergeben, ohne die Array-Dimensionen zu übergeben, nein, das können Sie nicht. Zumindest nicht für echte mehrdimensionale Arrays.
Sie können die Dimension setzen[s] in eine Struktur zusammen mit dem Array und behaupten, dass Sie ein “einzelnes Argument” übergeben, aber das ist wirklich nur das Packen mehrerer Werte in einen einzigen Container und das Aufrufen dieses Containers “ein Argument”.
Sie können ein Array mit bekanntem Typ und bekannter Anzahl von Dimensionen, aber unbekannter Größe übergeben, indem Sie die Dimensionen selbst und das Array wie folgt übergeben:
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" );
}
}
Sie würden diese Funktion wie folgt aufrufen:
int a[ 4 ][ 5 ];
int b[ 255 ][ 16 ];
...
print2dIntArray( 4, 5, a );
....
printt2dIntArray( 255, 16, b );
In ähnlicher Weise kann ein dreidimensionales Array von beispielsweise a struct pixel
:
void print3dPixelArray( size_t x, size_t y, size_t z, struct pixel pixelArray[ x ][ y ][ z ] )
{
...
}
oder ein 1-dimensional double
Array:
void print1dDoubleArray( size_t x, double doubleArray[ x ] )
{
...
}
ABER…
Es kann jedoch möglich sein, “Arrays von Zeigern an Arrays von Zeigern auf … ein Array des Typs zu übergeben X
” Konstrukte, die oft fälschlicherweise als “mehrdimensionales Array” als einzelnes Argument bezeichnet werden, solange der Basistyp X
hat einen Sentinel-Wert, der verwendet werden kann, um das Ende des letzten eindimensionalen Arrays des Typs auf der niedrigsten Ebene anzuzeigen X
.
Zum Beispiel die char **argv
Wert übergeben main()
ist ein Zeiger auf ein Array von Zeigern auf char
. Das anfängliche Array von char *
Zeiger enden mit a NULL
Sentinel-Wert, während jeder char
Array, auf das durch das Array von verwiesen wird char *
Zeiger enden mit a NUL
Zeichenwert von '\0'
.
Zum Beispiel, wenn Sie verwenden können NAN
als Sentinel-Wert, da die tatsächlichen Daten dies nicht tun je sei ein NAN
könnten Sie a drucken double **
so was:
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++;
}
}
Pedro
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
}
stackoverflow.com/questions/16943909/…
– Dchris
5. Juni 2013 um 16:02 Uhr
Dies ist kein 2D-Array, sondern eine Nachschlagetabelle. Auch dies ist mit C gekennzeichnet.
– Ludin
23. Juni 2015 um 10:45 Uhr
stackoverflow.com/questions/16943909/…
– Dchris
5. Juni 2013 um 16:02 Uhr
Dies ist kein 2D-Array, sondern eine Nachschlagetabelle. Auch dies ist mit C gekennzeichnet.
– Ludin
23. Juni 2015 um 10:45 Uhr