Mehrdimensionales Array als Funktionsparameter/ Pointer?!?



  • Hey liebe C-Freunde,

    ich hab immoment ein Problem mit mehrdimensionalen Arrays. Undzwar möchte ich ein Array zeilenweise bzw. spaltenweise kopieren um den Laufzeitunterschied aufzudecken. Soweit so gut. Nun möchte ich aber mein zu kopierendes Array als Funktionsparameter übergeben. Was muss ich dafür benutzen? Na klar Pointer auf das Array. Aber irgendwie spuckt mir meine Entwicklungsumgebung (Pelles C) immer folgenden Fehler aus : "\Test.c(12): error #2144: Type error: pointer expected." und ich verstehe nicht genau warum.

    Hier der Code:

    void kopierezeile(long *array1, int x, int y){
    double tDiff1, tStart1 = 0.0;
    int i,j;
    long arr2[100][100];
    
    tStart1 = getNanoSeconds();  
    for (i=0;i<x;i++){
     	for (j=0;j<y;j++){
     		arr2[i][j]=array1[i][j];
    	}
    }
    tDiff1 = getNanoSeconds() - tStart1;
    printf("Benötigte Zeit für das Kopieren(zeilenweise): %f nanoseconds.\n", tDiff1);
    }
    
    int main(int argc, char *argv[]) {
    	int x = 100, y = 100, a, b, counter = 0;
    	long array1[x][y];
    
    	for (a=0;a<y;a++){
     		for (b=0;b<x;b++){
        		array1[a][b]= counter;
    			counter = counter + 1;
    		}
    	}
    	kopierezeile(&array1[0][0], x, y);
    }
    

    Wahrscheinlich hab ich ein komplettes Pointergewusel veranstaltet oder ;)?

    MFG


  • Mod

    Das ist ja auch kein Pointer auf ein Array, das du da hast, sondern ein Pointer auf einen long. Und somit ist array1[i] ein long. Was ist dann array1[i][j] ? Unsinn. Daher beschwert sich der Compiler.

    Mehrdimensionale Arrays in C sind ein bisschen schwierig, meistens benutzt man sie einfach gar nicht. Du benutzt zudem noch VLAs (variable length arrays) was für Anfänger sicherlich noch schwieriger ist, da es recht obskure Regeln gibt, wie man ein VLA an eine Funktion übergeben kann und trotzdem den VLA-Typ behält (man kann natürlich auch "normale" Arrayübergabe mit VLAs benutzen). Ist das Absicht oder ein Versehen aus Unkenntnis?

    Folgendes wäre eine mögliche Lösung für dein Problem:

    void kopierezeile(long array1[][100], int x)
    

    P.S.: Bitte rück deinen Code ordentlich und konsistent ein!
    P.P.S: Und schalt bei solchen Messungen Compileroptimierungen ein! Hier kommt wahrscheinlich in beiden Fällen das gleiche raus, sofern die ganze Schleife nicht ohnehin wegoptimiert wird.



  • Danke erstmal für die Antwort. 😉

    Ups das mit dem Long ist ja echt fahrlässig. Das hätte ich auch selber merken können :(. Aber das mit den VLAs ist wohl eher aus Unwissenheit. Hab mir im Internet nen paar Beispiele zu zweidimensionalen Arrays angeguckt und einfach versucht das nachzumachen.

    Zu deiner Lösung:
    Das array1 hat das dann auch 100 Zeilen und Spalten? und wofür benötige ich das x dann?

    Wie genau schalte ich denn die Compileroptimierung ein?

    Ich hoffe ich nerve dich nicht zu sehr mit meinen Fragen 😉

    MFG


  • Mod

    C_Bob schrieb:

    Zu deiner Lösung:
    Das array1 hat das dann auch 100 Zeilen und Spalten? und wofür benötige ich das x dann?

    Nein, das ist ein Zeiger auf ein Array mit 100 Einträgen vom Typ long. Das ist ganz genau das gleiche Prinzip wie bei 1D-Arrays:

    void foo(int bar[], int size);
    

    bloß dass hier der Typ auf den der Zeiger zeigt eben nicht int ist, sondern long[100]. Auf wie viele long[100] der Zeiger zeigt, steht nicht fest.

    Wie genau schalte ich denn die Compileroptimierung ein?

    Kommt auf den Compiler an. Da gibt's bestimmt eine Anleitung für. Lerne, diese Anleitung zu finden und zu benutzen. (Falls du es nicht hinbekommst, dann fragst du hier nochmal nach, mit genauer Angabe, was du benutzt.)



  • Der Zeiger kann aberrum wieder auf ein 2D Array zeigen oder? Oder wie soll ich sonst das zeilenweise und spaltenweise kopieren mit einem 1D Array realisieren?

    MFG



  • Das Problem mit der Compiler Optimierung hab ich schon selber gelöst 😉

    MFG



  • Oder regel ich das einfach darüber, dass ich 2 Schleifen habe und dann jeweils die erste bzw. die zweite Zugriff auf das Array hat. Und somit das Sortieren eines 2D Arrays "simuliere"?

    MFG


  • Mod

    C-Bob schrieb:

    Der Zeiger kann aberrum wieder auf ein 2D Array zeigen oder? Oder wie soll ich sonst das zeilenweise und spaltenweise kopieren mit einem 1D Array realisieren?

    C_Bob schrieb:

    Oder regel ich das einfach darüber, dass ich 2 Schleifen habe und dann jeweils die erste bzw. die zweite Zugriff auf das Array hat. Und somit das Sortieren eines 2D Arrays "simuliere"?

    Beides ist möglich. Ich habe dir den Ansatz für das erste gegeben, da es zu deinem sonstigen Code passt. Der Ansatz für das zweite wäre dein alter Funktionskopf

    void kopierezeile(long *array1, int x, int y);
    

    du müsstest bloß den Code noch etwas anpassen.

    Allgemein kannst du ein 2D-Array, da es eine zusammenhängende Datenstruktur ist, auch über memcpy kopieren, was mit Abstand die schnellste Methode sein dürfte.



  • Gut dann setze ich mich da später mal dran ;). Vielen Dank für deine Hilfe SeppJ!:)

    MFG



  • hey ich bins nochmal 😉

    Also ich denke der Code müsste so für meine Zwecke stimmen oder? Nun krieg ich aber genau das Problem was du bereits erwähnt hast SeppJ: Ich bekomme bei beiden Methoden den gleichen Zeitaufwand. Das liegt wahrscheinlich daran, dass die Schleifen wegoptimiert werden richtig? Nur wie kann ich das umgehen? Ich benutze zur Zeit Pelles C als Entwicklungsumgebung und kann dort die Compiler Optimization einstellen (Entweder auf Aus, Maximize Speed, Minimize Size, Maximize Speed more oder Minimize Size more). Nur weiß ich nichts genau damit anzufangen.

    Hier mein Code:

    void kopierezeile(long *array1, int x, int y){
    	double tDiff1, tStart1 = 0.0;
    	int i,j;
    	long arr2[100];
    
    	tStart1 = getNanoSeconds();  
    	for (i=0;i<x;i++){
     		for (j=0;j<y;j++){
     			arr2[i]=array1[i];
    		}
    	}
    
    	tDiff1 = getNanoSeconds() - tStart1;
    	printf("Benötigte Zeit für das Kopieren(zeilenweise): %f nanoseconds.\n", tDiff1);
    }
    
    void kopierespalte(long *array1, int x, int y){
    	double tDiff2, tStart2 = 0.0;
    	int u,v;
    	long arr3[100];
    
    	tStart2 = getNanoSeconds(); 
    	for (u=0;u<y;u++){
     		for (v=0;v<x;v++){
       		 	arr3[v]=array1[v];
    		}
    	}
    
    	tDiff2 = getNanoSeconds() - tStart2;
    	printf("Benötigte Zeit für das Kopieren(spaltenweise): %f nanoseconds.\n", tDiff2);
    }
    
    int main(int argc, char *argv[]) {
    	int x = 100, y = 100, a, counter = 0;
    	long array1[x];
    
    	for (a=0;a<y;a++){
        	array1[a]= counter * 10002,5234234;
    		counter = counter + 1;
    	}
    
    	kopierezeile(&array1[0], x, y);
    	kopierespalte(&array1[0], x, y);
    }
    

    Vielleicht kann mir ja nochmal jemand helfen 😉

    MFG



  • Okay Update:
    Wenn ich die Größe des Arrays auf 1000 erhöhe, dann werden erste Unterschiede deutlich 🙂 👍 . Stimmt mein Code denn so? (Außer, dass ich in der Main for schleife aus versehen das y anstatt x zum Vergleich verwende 😉 Hab ich schon geändert.)

    MFG


  • Mod

    Beide Codes haben sehr viele Fehler an sehr vielen Stellen und machen nicht einmal entfernt das was du denkst.

    Verdächtige Zeilen sind: 2, 7, 10, 14, 20, 25, 28, 32, 37, 39 und 42. Mit Abstrichen auch 43, 46, 47.

    Das erkläre ich nicht alles im Details. Das sind teilweise ziemliche Anfängerfehler. Es sieht aus wie zur einen Hälfte schlecht abgeschrieben und zur anderen Hälfte durch ausprobieren programmiert. -> Du kannst die Anfängersachen nicht. -> Du musst diese zuerst lernen. -> Guck dir mal die als wichtig markierten Threads im Forum an.



  • C_Bob schrieb:

    Ich bekomme bei beiden Methoden den gleichen Zeitaufwand. Das liegt wahrscheinlich daran, ...

    Die Crux der Anfänger: anstatt erstmal für funktionierenden Code zu sorgen, werden gleich Annahmen über das Performanz- und Optimierungsverhalten des Compilers gemacht.
    Das ist, wie man sieht, eher wenig zuträglich für ein zufriedenstellendes Endergebnis der Gesamtaufgabenstellung.


Anmelden zum Antworten