zweidimensionales Array von Strings
-
ist
char ***foo;
"nur" ein 3-Dim Array? Quatsch oder? Wie wird sowas übergeben und derefferenziert?
-
Nein, das ist kein 3D-Array.
Ein (echtes) 3D-Array zerfällt auch nur in einen einfachen Zeiger.newbie110 schrieb:
Wie wird sowas übergeben und derefferenziert?
char **bar(char ***foo) // ***foo ist ein char { putchar(foo[3][2][1]); // das kannst du 3mal dereferenzieren puts (foo[3][2]); // Einmal weniger dereferenziert ist dann char* return foo[3]; // das ist dann char** (sowas wie argc von main) }
-
Aha...Danke!!
Noch ne Frage... Wie würde das dann aussehne, wenn der 3-Star zb. auf ne Struktur zeigt?
Also z.B.:
struct v1{int t1; int t2}}; typedef struct v1 TEST; // ginge dann sowas??: TEST ***tptr;
Sinn und oder Unsinn sei jetzt mal dahin gestellt. Geht sowas, und wenn ja, wie handelt man das dann?
-
newbie110 schrieb:
Aha...Danke!!
Noch ne Frage... Wie würde das dann aussehne, wenn der 3-Star zb. auf ne Struktur zeigt?
Also z.B.:
struct v1{int t1; int t2}}; typedef struct v1 TEST; // ginge dann sowas??: TEST ***tptr;
Sinn und oder Unsinn sei jetzt mal dahin gestellt. Geht sowas, und wenn ja, wie handelt man das dann?
Ist doch einfach:
#include <stdio.h> typedef struct { int id; } T_ID; int main( void ) { T_ID myId = { 5 }; T_ID *fp1 = &myId; T_ID **fp2 = &fp1; T_ID ***fp3 = &fp2; printf( "%d", (**fp3)->id ); return 0; }
-
Ui, interessant....
Wie würde sowas dann mit SeppJ´s Beispiel aussehen??
Variante 3: Wörter unterschiedlich groß, unbekannte Zahl von Worten pro Zeile, unbekannte Zahl von Zeilen:
C: char ***foo;
Wie "schreibt" man da rein und kann das auslesen??
-
beginner88888 schrieb:
Ui, interessant....
Wie würde sowas dann mit SeppJ´s Beispiel aussehen??
Variante 3: Wörter unterschiedlich groß, unbekannte Zahl von Worten pro Zeile, unbekannte Zahl von Zeilen:
C: char ***foo;
Wie "schreibt" man da rein und kann das auslesen??
Wo ist das Problem? Das geht ganz normal:
***foo = 'c'; // oder char c = ***foo;
-
beginner88888 schrieb:
Wie "schreibt" man da rein und kann das auslesen??
SeppJ schrieb:
Dann nutzt du malloc um die Felder unbekannter Größe zu bekommen.
Du solltest wirklich mal an kleineren Beispielen üben, wenn du solche Fragen stellen musst. An den gezeigten Techniken ist nicht anders als an "normalen" eindimensionalen Strukturen. Nur eben dreifach verschachtelt und jede Ebene ist dann entweder dynamisch oder statisch. Sie wird aber jeweils genau so behandelt wie im einfachen Fall. Das nützt dir natürlich herzlich wenig, wenn du den einfachen Fall nicht beherrscht, was ich mal anhand deiner Fragen annehme. Falls du Probleme mit mit der dreifachen Verschachtelung hast, gilt ebenfalls weiter üben. Denn Verschachtelungen brauchst du andauernd beim Programmieren, damit darfst du keine Schwierigkeiten haben. Beide Themenbereiche sollten in jedem Lehrbuch drankommen.
-
SeppJ schrieb:
Du solltest wirklich mal an kleineren Beispielen üben, wenn du solche Fragen stellen musst. An den gezeigten Techniken ist nicht anders als an "normalen" eindimensionalen Strukturen. Nur eben dreifach verschachtelt und jede Ebene ist dann entweder dynamisch oder statisch. Sie wird aber jeweils genau so behandelt wie im einfachen Fall. Das nützt dir natürlich herzlich wenig, wenn du den einfachen Fall nicht beherrscht, was ich mal anhand deiner Fragen annehme. Falls du Probleme mit mit der dreifachen Verschachtelung hast, gilt ebenfalls weiter üben. Denn Verschachtelungen brauchst du andauernd beim Programmieren, damit darfst du keine Schwierigkeiten haben. Beide Themenbereiche sollten in jedem Lehrbuch drankommen.
In diesem Zusammenhang fällt mir folgendes kleines Beispiel ein.
Wie man ja weiß werden Arrays nicht "by value" an Funktionen übergeben sondern stattdessen wird deren Adresse übergeben. D.h.func( char *x ) {}
und
func( char x[] ) {}
sind identisch.
Jetzt könnte ein Anfänger auf die Idee kommen, bei mehrdimensinalen Arrays kann man einfach alle Arrayindizes durch das Zeigersymbol ersetzen. also statt
func( char x[][10][20] ) {}
geht auch
func( char ***x ) {}
Das ist aber falsch. Erste Funktion erwartet einen Zeiger auf ein zweidimensinales Array und die zweite erwartet einen Zeiger auf einen Zeiger auf einen Zeiger. Die Dereferenzierung erzeugt daher völlig unerschiedlichen Code.
func( char x[][10][20] ) { return x[0][0][0]; }
func( char ***x ) { return x[0][0][0]; }
Für diejenigen, die da mal selber rumspielen wollen, habe ich meinen Code von vorher etwas erweitert:
#include <stdio.h> #include <stdlib.h> typedef struct { int id; } T_ID; char ReadMultiArray( char array[][200][300], int x, int y, int z ) { return array[x][y][z]; } char ReadMultiArray2( char ***array, int x, int y, int z ) { return array[x][y][z]; } int main( void ) { char my3Darray[100][200][300]; char (*myDynamic3Darray)[200][300] = calloc( 100 * 200 * 300, sizeof( char) ); char *myDynamic3Darray2[200][300]; T_ID myId = { 5 }; T_ID *fp1 = &myId; T_ID **fp2 = &fp1; T_ID ***fp3 = &fp2; printf( "%d\n", (**fp3)->id ); printf( "%d\n", (int)sizeof( myDynamic3Darray ) ); printf( "%d\n", (int)sizeof( myDynamic3Darray2 ) ); printf( "%d\n", (int)ReadMultiArray( my3Darray, 5, 5, 5 ) ); printf( "%d\n", (int)ReadMultiArray( myDynamic3Darray, 5, 5, 5 ) ); printf( "%d\n", (int)ReadMultiArray2( my3Darray, 5, 5, 5 ) ); // <--- das gibt 'nen Absturz return 0; }
In Zeile 21 deklariere ich ein 3-dimensionales Array.
Brauche ich das aber dynamnisch, muß ich eine Deklaration wie in Zweile 22 verwenden. Man beachte die Klammern. In Zeile 23 wird nämlich ein zweidimensonales Array von Zeigern deklariert. Das sieht man sehr schön an der Ausgabe der Zeilen 32 und 33.Die Zeilen 35 und 36 demonstrieren den Zugriff auf die beiden dreidimensionalen Arrays. Zeile 37 erzeugt einen Absturz. Diese wird aber auch schon vom Compiler angemahnt (In C++ wäre das sogar ein Fehler).
Will man ein 3-dimensinales Array bei dem alle drei Arraygrenzen dynamisch festgelegt werden können, muß man in C schon etwas mehr Aufwand betreiben.
mfg Martin
-
mgaeckler schrieb:
Will man ein 3-dimensinales Array bei dem alle drei Arraygrenzen dynamisch festgelegt werden können, muß man in C schon etwas mehr Aufwand betreiben.
Auch dafür habe ich ein Beispiel gemacht:
#include <stdio.h> #include <stdlib.h> typedef struct { size_t maxX, maxY, maxZ; char start[]; } ARRAY_3d; ARRAY_3d *createArray( size_t maxX, size_t maxY, size_t maxZ ) { ARRAY_3d *newArray = malloc( sizeof( ARRAY_3d ) + maxX * maxY * maxZ ); newArray->maxX = maxX; newArray->maxY = maxY; newArray->maxZ = maxZ; return newArray; } size_t getIndex( ARRAY_3d*array, size_t x, size_t y, size_t z ) { return x + y*array->maxX + z * array->maxX * array->maxY; } void setChar( ARRAY_3d*array, size_t x, size_t y, size_t z, char c ) { array->start[getIndex( array, x, y, z )]=c; } char getChar( ARRAY_3d*array, size_t x, size_t y, size_t z ) { return array->start[getIndex( array, x, y, z )]; } int main( void ) { size_t x, y, z; ARRAY_3d *array = createArray(5,5,5); for( x=0;x<5;x++ ) { for( y=0;y<5;y++ ) { for( z=0;z<5;z++ ) { setChar( array, x, y, z, z+'A' ); } } } for( x=0;x<5;x++ ) { for( y=0;y<5;y++ ) { for( z=0;z<5;z++ ) { putchar( getChar( array, x, y, z ) ); } } putchar ('\n' ); } return 0; }
Fehlerprüfung etc. habe ich jetzt nicht gemacht.
mfg Martin
-
Danke für die tollen Beispiele.
Das nützt dir natürlich herzlich wenig, wenn du den einfachen Fall nicht beherrscht, was ich mal anhand deiner Fragen annehme. Falls du Probleme mit mit der dreifachen Verschachtelung hast, gilt ebenfalls weiter üben.
Die einfachen gehen mittlerweile realtiv gut. Hab das Thema hier einfach entdeckt und bin hald bisschen neugierig geworden. Reine Interessesache