Zweidimensionales Array an Funktion übergeben - Problem bei allen Spalten >1



  • online codegenerator schrieb:

    probier's so:
    ...

    das ist ein schönes beispiel vie man flexibel mit arrays verschiedener anzahl von zeilen und spalten arbeiten kann.
    wenn man noch den index ändern würde, dann würden die zahlen auch in der richtigen reihenfolge ausgegeben werden, 😮
    z.b. so:

    void drucken_reprogged( int *feld, int zeilen, int spalten )
    {
        int count_zeilen;
        int count_spalten;
        for ( count_zeilen = 0; count_zeilen < zeilen; count_zeilen++ )
        {
            for ( count_spalten = 0; count_spalten < spalten; count_spalten++ )
            {
                printf ( "%3d", feld[count_zeilen*spalten+count_spalten] ); // !!!
            }
            printf ("\n");
        }
    }
    

    🕶

    wenn die größe des arrays aber feststeht und sich nicht ändert, gehts aus so:

    void drucke2Darr( int arr[ZEILEN][SPALTEN] )
    {
    	int z,s;
    
    	for( s=0; s<SPALTEN; s++ )
    	{
    		for ( z=0; z<ZEILEN; z++ )
    		{
    			printf( "%3d", arr[z][s] );
    		}
    		puts("");
    	}
    }
    
    void init2Darr( int arr[ZEILEN][SPALTEN] )
    {
    	int i = 0,z,s;
    	for( s=0; s<SPALTEN; s++ )
    		for ( z=0; z<ZEILEN; z++ )
    	 arr[z][s] = i++;
    }
    // aufruf
    init2Darr(arr);
    drucke2Darr(arr);
    drucken_reprogged( arr, ZEILEN, SPALTEN )
    

    🙂



  • Die Lösung setzt aber voraus, dass ich ZEILEN und SPALTEN vorher per "#define" definiert habe, oder? Sonst funktioniert es nämlich bei mir nicht...
    Kann ich statt des festen Wertes denn auch den Wert für ZEILEN und SPALTEN während des Programmaufrufs festlegen (z.B. durch eine Eingabe)? Das muss ich nämlich: das Array kann für jeden Programmaufruf eine andere Größe haben 😞
    Trotzdem danke...



  • Übrigens ist mir grade aufgefallen, dass ich das Thema falsch benannt habe: ich habe natürlich Schwierigkeiten in allen Zeilen > 1 🙄



  • c-anfaenger schrieb:

    Kann ich statt des festen Wertes denn auch den Wert für ZEILEN und SPALTEN während des Programmaufrufs festlegen (z.B. durch eine Eingabe)? Das muss ich nämlich: das Array kann für jeden Programmaufruf eine andere Größe haben 😞
    Trotzdem danke...

    das kannst du mit 'malloc' machen:

    ...
    int zeilen = ...;
    int spalten = ...;
    int *feld = malloc (zeilen * spalten * sizeof(int));
    ...
    if (feld) // nur benutzen wenn feld != 0
    {
       feld[x+zeilen*y] = ...;  // setzt einen wert an position x/y
       ...
       free (feld);             // 'free' aufrufen wenn feld nicht mehr gebraucht wird 
    }
    

    🙂



  • c-anfaenger schrieb:

    Alternativ habe ich auf galileocomputing gelesen, dass man auch einen Pointer übergeben kann (http://www.galileocomputing.de/openbook/c_von_a_bis_z/c_014_006.htm#RxxobKap014006040028C01F04118C). Dann bekomme ich allerdings beim kompilieren die Fehlermeldung...

    btw: vergiss 'galileo-computing' am besten ganz schnell. das ist voller fehler. frag' lieber uns.
    🙂



  • falls dir die indexschreibweise eher zusagt:

    void init_arr2D( int **arr, int zeilen, int spalten )
    {
    	int i = 0,z,s;
    
    	for( z=0; z<zeilen; z++ )
    		for ( s=0; s<spalten; s++  )
    			 arr[z][s] = i++;
    }
    
    void drucken_arr2D( int **arr, int zeilen, int spalten )
    {
        int z;
        int s;
        for ( z = 0; z < zeilen; z++ )
        {
            for ( s = 0; s < spalten; s++ )
            {
                printf ( "%3d", arr[z][s] );  
            }
            puts("");
        }
    }
    
    int main()
    {
     	int i=0,j=0,z=3,s=5;
    	int** arr2D=NULL;
    
    	arr2D = malloc( z*sizeof(int**) );
    	if ( !arr2D ) 
    	{
    		puts("out of memory"); return 1;
    	}
    
    	for ( i=0; i<z; i++ )
    	{
    		arr2D[i] = malloc( s*sizeof(int));
    		if ( !arr2D[i]) break;
    	}
    
    	if ( i<z )
    	{
    		puts("out of memory");
    		for ( j=0; j<=i; j++ ) free ( arr2D[j] );
    		free( arr2D ); 
    		return 1;
    	}
    
    	init_arr2D(arr2D, z, s);
    	drucken_arr2D(arr2D, z, s );
    
    	// aufräumen
    	for ( i=0; i<z; i++ )
    	{
    		free(arr2D[i]); // spalten freigeben
    	}
    	free(arr2D); // zeilenzeiger freigeben 
    
    	return 0;
    }
    

    🙂



  • Vielen Dank! 👍



  • Das beispiel von easy array II reprogged funktioniert leider nicht. Ich bekomme jede Menge Fehler:

    Fehler 1 error C3861: "printf": Bezeichner wurde nicht gefunden. h:\visual studio 2010\projects\basics\basics\main.cpp 18
    Fehler 2 error C3861: "puts": Bezeichner wurde nicht gefunden. h:\visual studio 2010\projects\basics\basics\main.cpp 20
    Fehler 3 error C2065: 'NULL': nichtdeklarierter Bezeichner h:\visual studio 2010\projects\basics\basics\main.cpp 27
    Fehler 4 error C3861: "malloc": Bezeichner wurde nicht gefunden. h:\visual studio 2010\projects\basics\basics\main.cpp 29
    Fehler 5 error C3861: "puts": Bezeichner wurde nicht gefunden. h:\visual studio 2010\projects\basics\basics\main.cpp 32
    Fehler 6 error C3861: "malloc": Bezeichner wurde nicht gefunden. h:\visual studio 2010\projects\basics\basics\main.cpp 37
    Fehler 7 error C3861: "puts": Bezeichner wurde nicht gefunden. h:\visual studio 2010\projects\basics\basics\main.cpp 43
    Fehler 8 error C3861: "free": Bezeichner wurde nicht gefunden. h:\visual studio 2010\projects\basics\basics\main.cpp 44
    Fehler 9 error C3861: "free": Bezeichner wurde nicht gefunden. h:\visual studio 2010\projects\basics\basics\main.cpp 45
    Fehler 10 error C3861: "free": Bezeichner wurde nicht gefunden. h:\visual studio 2010\projects\basics\basics\main.cpp 58
    Fehler 11 error C3861: "free": Bezeichner wurde nicht gefunden. h:\visual studio 2010\projects\basics\basics\main.cpp 60
    12 IntelliSense: PCH-Warnung: Es wurde keine geeignete Stelle für das Header-Ende gefunden. Es wurde keine Intellisense-PCH-Datei generiert. h:\visual studio 2010\projects\basics\basics\main.cpp 1
    13 IntelliSense: Der Bezeichner ""printf"" ist nicht definiert. h:\visual studio 2010\projects\basics\basics\main.cpp 18
    14 IntelliSense: Der Bezeichner ""puts"" ist nicht definiert. h:\visual studio 2010\projects\basics\basics\main.cpp 20
    15 IntelliSense: Der Bezeichner ""NULL"" ist nicht definiert. h:\visual studio 2010\projects\basics\basics\main.cpp 27
    16 IntelliSense: Der Bezeichner ""malloc"" ist nicht definiert. h:\visual studio 2010\projects\basics\basics\main.cpp 29
    17 IntelliSense: Der Bezeichner ""puts"" ist nicht definiert. h:\visual studio 2010\projects\basics\basics\main.cpp 32
    18 IntelliSense: Der Bezeichner ""puts"" ist nicht definiert. h:\visual studio 2010\projects\basics\basics\main.cpp 43
    19 IntelliSense: Der Bezeichner ""free"" ist nicht definiert. h:\visual studio 2010\projects\basics\basics\main.cpp 44
    20 IntelliSense: Der Bezeichner ""free"" ist nicht definiert. h:\visual studio 2010\projects\basics\basics\main.cpp 45
    21 IntelliSense: Der Bezeichner ""free"" ist nicht definiert. h:\visual studio 2010\projects\basics\basics\main.cpp 58
    22 IntelliSense: Der Bezeichner ""free"" ist nicht definiert. h:\visual studio 2010\projects\basics\basics\main.cpp 60



  • Da fehlen Header:

    #include <stdio.h>
    #include <stdlib.h>

    ganz oben sollte helfen.



  • Leichenfledderer.

    Liebe Kinder, so nicht machen

    #include <stdio.h>
    #include <stdlib.h>
    
    int spalten;
    
    //Druck-Funktion
    void drucken (int feld[][spalten], int zeilen, int spalten) {
        for ( int count_zeilen = 0; count_zeilen < zeilen; count_zeilen++ ) {
            for ( int count_spalten = 0; count_spalten < spalten; count_spalten++ ) {
                printf ( "%3d", feld[count_zeilen][count_spalten] );
            }
            printf ("\n");
        }
    }
    
    //Main-Funktion
    int main (void) {
        int zeilen = 2;
        spalten = 2;
        int feld [zeilen][spalten];
    
        for ( int count_zeilen = 0; count_zeilen < zeilen; count_zeilen++ ) {
            for ( int count_spalten = 0; count_spalten < spalten; count_spalten++ ) {
                feld[count_zeilen][count_spalten] = count_zeilen + count_spalten;
            }
        }
    
        drucken (feld, zeilen, spalten);
    }
    

    Der Onkel zeigt jetzt mal, wie man sowas macht:
    - ohne globale Variablen
    - ohne VLA
    - ohne UB
    - ohne Zeiger-Cast
    - C99 konform (wegen Verwendung von Zeigern auf VLA)
    - im Übrigen kommen in den meisten o.g. "Vorschlägen" überhaupt keine Arrays vor
    - es gibt auch keine zweidimensionalen Arrays sondern nur Arrays von Arrays

    void setzen (void *speicher, int zeilen, int spalten) {
    	int (*f)[spalten] = speicher;
        for ( int count_zeilen = 0; count_zeilen < zeilen; count_zeilen++ ) {
            for ( int count_spalten = 0; count_spalten < spalten; count_spalten++ ) {
                f[count_zeilen][count_spalten] = count_zeilen + count_spalten;
            }
        }
    }
    
    void drucken (void *speicher, int zeilen, int spalten) {
    	int (*f)[spalten] = speicher;
        for ( int count_zeilen = 0; count_zeilen < zeilen; count_zeilen++ ) {
            for ( int count_spalten = 0; count_spalten < spalten; count_spalten++ ) {
                printf ( "%3d", f[count_zeilen][count_spalten] );
            }
            printf ("\n");
        }
    }
    
    int main (void) {
        int zeilen = 2;
        int spalten = 2;
        int *speicher = malloc( zeilen*spalten*sizeof*speicher );
    
    	setzen  (speicher, zeilen, spalten);
        drucken (speicher, zeilen, spalten);
    
        free( speicher );
        return 0;
    }
    

    http://ideone.com/vTPuBH

    Das Ganze arbeitet mit Dimensionen, die erst zur Laufzeit bekannt sind auf einem Speicherbereich, d.h. es wird auch nur 1x malloc/free verwendet (was in der Regel ziemlich teuer ist).
    Weiterhin kann die offensichtlich ja wohl gewünschte Doppelsubskription [zeile][spalte] verwendet werden, die bei den meisten o.g. Beispielen zu der irrigen Annahme führte, es handele sich um Arrays.


Anmelden zum Antworten