Anfängerfrage zu mehrdimensionalen Arrays



  • Hallo an die Community

    Mein Name ist Markus und ich bin beim Programmieren eigentlich noch blutiger Anfänger und daher bei Udemy einen C++ Kurs gebucht. Am Anfang ging alles eigentlich einfach, doch jetzt bei mehrdimensionalen Arrays blicke ich nicht mehr durch.
    Die Aufgabe ist: Erstelle ein 2D Array und fülle es mit double Werten.
    Schreib danach eine Routine mit der die Summe der Zeilen und die Summe der Spalten ausgegeben werden.

    Bei der Summe der Zeilen hab ich es noch so hinbekommen auch mithilfe der Tipps des dortigen Dozenten.

    #include <iostream>
    
    using std::cout;
    using std::endl;
    using std::cin;
    
    int main()
    {
    	// Matrix M 3x2, reelle (double)
    	double M[3][2] = 
    	{
    		{0.1, 0.2},
    		{0.3, 0.4},
    		{0.5, 0.6}
    	};
    	double sums[3] = { 0.0, 0.0, 0.0 };
    	for (int i = 0; i < 3; i++)
    	{
    		double sum = 0.0;
    
    		for (int j = 0; j < 2; j++)
    		{
    			sum += M[i][j];
    		}
    
    		sums[i] = sum;
    	}
    	for (int i = 0; i < 3; i++)
    	{
    		cout << endl << "In line " << i << " is the sum: " << sums[i];
    	}
    	cin.get();
    	getchar();
    	return 0;
    }
    

    Jetzt wollte ich es erweitern um auch die Spaltensumme auszugeben

    int main()
    {
    	// Matrix M 3x2, reelle (double)
    	
    	int M[3][2] =
    	{
    		{1, 2},
    		{3, 4},
    		{5, 6}
    	};
    	int sums[3] = {};
    	int sums2[2] = {};
     
    	for (int i = 0; i < 3; i++)
    	{
    		int sum = 0;
    		for (int j = 0; j < 2; j++)
    		{
    			sum += M[i][j];
    		}
    		sums[i] = sum;
    	}
    	for (int i = 0; i < 3; i++)
    	{
    		cout << endl << "In line " << i << " is the sum: " << sums[i];
    	}
    	for (int i = 0; i < 3; i++)
    	{
    		int sum2 = 0;
    		for (int j = 0; j < 2; j++)
    		{
    			sum2 += M[j][i];
    			sums2[j] = sum2;
    		}
    			}
    	for (int j = 0; j < 3; j++)
    	{
    		cout << endl << "In Column " << j << " is the sum: " << sums2[j];
    	}
    	cin.get();
    	getchar();
    	return 0;
    

    Doch da kommt leider nur mehr Mist raus. WIe gesagt irgendwie verstehe ich die mehrdimensionalen Arrays nicht wirklich, ich brüte jetzt wirklich schon sehr lange darüber, vielleicht kann mir jemand zumindest einen Stoß in die richtige Richtung geben damit ich verstehe wo hier mein fundamentaler Denkfehler liegt.

    Danke euch im voraus


  • Mod

    Erklär doch mal, wieso die Zeilen 16-21 einen anderen Aufbau haben als 29-34, wenn sie doch eigentlich essentiell das gleiche machen sollen.



  • @montanistikus1 sagte in Anfängerfrage zu mehrdimensionalen Arrays:

    for (int i = 0; i < 3; i++)
    {
    int sum2 = 0;
    for (int j = 0; j < 2; j++)
    {
    sum2 += M[j][i];
    sums2[j] = sum2;
    }
    }
    for (int j = 0; j < 3; j++)
    {
    cout << endl << "In Column " << j << " is the sum: " << sums2[j];
    }

    Du hast hier Speicherzugriffsfehler. Du berechnest drei Kolonnen aus. Hast aber nur zwei. Dein sums2[j] = ... muss in deine äußere Schleife. Schau dir an wie du es bei den Zeilen gemacht hast, du musst die Indexes nur umkehren.



  • Ich möchte mich einmal für die superschnellen Antworten bedanken, ich habe mir jetzt überlegt wo der Fehler ist.
    Ich habe es jetzt folgendermaßen probiert und auf die Anregung von euch hin die Block für die Zeilen nochmals für die Spalten modifiziert. Es compiliert zwar ohne Probleme gibt aber immer noch nur Mist noch.
    Als Anfänger kannst da wirklich wahnsinnig werden weil ich irgendwie das Gefühl habe irgendeinen fundamentalen Denkfehler drinnen zu haben aber ich kapier einfach nicht welchen

    #include <iostream>
    
    using std::cout;
    using std::endl;
    using std::cin;
    
    int main()
    {
    	// Matrix M 3x2, reelle (double)
    	double M[3][2] =
    	{
    		{0.1, 0.2},
    		{0.3, 0.4},
    		{0.5, 0.6}
    	};
    	double sums[3] = { 0.0, 0.0, 0.0 };
    	for (int i = 0; i < 3; i++)
    	{
    		double sum = 0.0;
    
    		for (int j = 0; j < 2; j++)
    		{
    			sum += M[i][j];
    		}
    
    		sums[i] = sum;
    	}
    	for (int i = 0; i < 3; i++)
    	{
    		cout << endl << "In line " << i << " is the sum: " << sums[i];
    	}
    	double sums2[2] = { 0.0, 0.0};
    	for (int i = 0; i < 2; i++)
    	{
    		double sum2 = 0.0;
    
    		for (int j = 0; j < 2; j++)
    		{
    			sum2 += M[j][i];
    		}
    
    		sums2[i] = sum2;
    	}
    	for (int i = 0; i < 2; i++)
    	{
    		cout << endl << "In Column " << i << " is the sum: " << sums2[i];
    	}
    	cin.get();
    	getchar();
    	return 0;
    }
    

  • Mod

    Besser, aber offensichtlich noch nicht richtig. Wobei es hilfreich wäre, wenn du Probleme genauer beschreiben könntest als "nur Mist". Denn mit einer guten Beschreibung kann man gezielter nach Problemen suchen, anstatt deinen ganzen Code durchlesen zu müssen.
    Zurück zum Thema: Da ist immer noch ein Unterschied zwischen den beiden Blöcken für die Zeilen und die Spalten. Die Struktur ist jetzt zwar gleich, aber du hast beim Spiegeln der Indizes eine Sache vergessen (oder noch genauer: Eine Sache hast du nur halb gespiegelt). Schau noch einmal ganz genau hin auf die beiden Blöcke: Was ist gleich, was hast du geändert, und passt das alles zusammen?



  • Danke dir Sepp dass du dir die Zeit nimmst, ja wenn man ganz am Anfang steht ist es oft zäh. Und du hast Recht Mist müsste man genauer definieren. Ok beim Ergebnis sind die folgenden Zeilenergebnisse zu erwarten: 0.3 ; 0.7 und 1.1
    das wird auch richtig ausgegeben. Bei den Spalten wären die Ergebnisse 0.9 und 1.2 zu erwarten als Resultat bekomme ich 0.4 und 0.6 also kein richtiges Ergebnis.

    Weil du sagtest ich habe den Block nur halb umgeschrieben habe ich gerade nochmals versucht diesen anzupassen

    double sums2[2] = { 0.0, 0.0 };
    	for (int i = 0; i < 3; i++)
    	{
    		double sum2 = 0.0;
    
    		for (int j = 0; j < 2; j++)
    		{
    			sum2 += M[j][i];
    		}
    
    		sums2[i] = sum2;
    	}
    	for (int j = 0; j < 2; j++)
    	{
    		cout << endl << "In Column " << j << " is the sum: " << sums2[j];
    	}
    

    Ergebnis bleibt das gleiche, also der Denkfehler ist noch da wobei ich inzwischen wie ein Brett vor dem Kopf und das Gef+hl habe gar nix mehr zu verstehen.



  • @montanistikus1 sagte in Anfängerfrage zu mehrdimensionalen Arrays:

    habe den Block nur halb umgeschrieben

    Poste trotzdem kompletten Code. Niemand hat Lust sich das zusammenszustückeln. Du kannst Deinen Beitrag im Nachhinein bearbeiten. Den Menüpunkt "Bearbeiten" findest Du hinter dem Drei-Punkte-Menü rechts unter Deinem Beitrag.



  • @montanistikus1: Da dein 2-dimensionales Array als M[3][2] definiert ist, darfst du mittels M[i][j] nur mit passenden Indexwerten darauf zugreifen (also für i nur Werte von 0 bis 2 und für j nur von 0 bis 1) - dies mußt du also bei deinen Schleifen beachten (analog gilt diese Aussage natürlich dann für den Zugriff mittels M[j][i], nur eben umgekehrt).



  • lieber Th69

    Ich sehe da in meinen Schleifen keinen Fehler habe i < 3 und j < 2 gesetzt also wird ohnehin nur der von dir genannte Wertebereich durchlaufen.

    @ sword

    Du hast recht habe den gesamten Code aber eh oben gepostet habe nur im letzten Beitrag nur mehr den zweiten Funktionsblock gepostet da laut Sepp ja eigentlich dort drinnen der Fehler liegt.
    Denn der Block der die Zeilensumme ausgibt der funktioniert ja tadellos



  • Um Spalten- statt Zeilensummen zu bilden, mußt du die Schleifen vertauschen, aber den Zugriff auf das Array beibehalten.
    Du greifst aber mittels M[j][i] zu - und nicht mittels M[i][j]!



  • Vielen Dank Th jetzt erkenne ich was für ein Volltro... ich war klar einfach die Schleifen umtauschen und den Parameter.
    Ich glaub jetzt verstehe ich es, hab das ganze jetzt so umgebaut und jetzt endlich tut das Programm so wie es sein soll.
    Vielen Dank jetzt ists mir auch klar geworden wieso

    #include <iostream>
    
    using std::cout;
    using std::endl;
    using std::cin;
    
    int main()
    {
    	// Matrix M 3x2, reelle (double)
    	double M[3][2] =
    	{
    		{0.1, 0.2},
    		{0.3, 0.4},
    		{0.5, 0.6}
    	};
    	double sums[3] = { 0.0, 0.0, 0.0 };
    	for (int i = 0; i < 3; i++)
    	{
    		double sum = 0.0;
    
    		for (int j = 0; j < 2; j++)
    		{
    			sum += M[i][j];
    		}
    
    		sums[i] = sum;
    	}
    	for (int i = 0; i < 3; i++)
    	{
    		cout << endl << "In line " << i << " is the sum: " << sums[i];
    	}
    	double sums2[2] = { 0.0, 0.0 };
    	for (int j = 0; j < 2; j++)
    	{
    		double sum2 = 0.0;
    
    		for (int i = 0; i < 3; i++)
    		{
    			sum2 += M[i][j];
    		}
    
    		sums2[j] = sum2;
    	}
    	for (int j = 0; j < 2; j++)
    	{
    		cout << endl << "In Column " << j << " is the sum: " << sums2[j];
    	}
    	cin.get();
    	getchar();
    	return 0;
    }
    


  • Geht das nicht in weniger Zeit? Jedes Element muss doch nur einmal durchlaufen werden. Just sayin'



  • Wahrscheinlich gehts in weniger Zeit wie gesagt ich bin erst seit 3 Wochen da mit dabei beim C++ Kurs von Jan Schaffranek auf Udemy 20 Jahre nach Ende meines Studiums. Für mich ist es ein Hobby aber ich bin immer noch bei den Grundlagen, komme jetzt erst ins Kapitel Vector, Pointer und Referenzen.

    Wäre aber gespannt wenn du mir zeigen könntest wie es effektiver geht, als Anfänger gibt man sich glaube ich schon mal damit zufrieden wenn es so läuft wie es laufen soll



  • @montanistikus1

    #include <cstddef>
    #include <vector>
    #include <iostream>
    
    void sum_up(double *matrix, std::size_t rows, std::size_t columns)
    {
    	std::vector<double> column_sums(columns);
    	for (std::size_t y = 0; y < rows; ++y) {
    		double row_sum{};
    		for (std::size_t x = 0; x < columns; ++x) {
    			row_sum += matrix[y * columns + x];
    			column_sums[x] += matrix[y * columns + x];
    			std::cout << matrix[y * columns + x] << ' ';
    		}
    		std::cout << "= " << row_sum << '\n';
    	}
    	for (std::size_t i = 0; i < columns; ++i)
    		std::cout << column_sums[i] << ' ';
    	std::cout.put('\n');
    }
    
    
    int main()
    {
    	double M[3][2] =
    	{
    		{0.1, 0.2},
    		{0.3, 0.4},
    		{0.5, 0.6}
    	};
    
    	sum_up((double*)M, 3, 2);
    }
    

    Zum Beispiel. Aber es gibt mehrere Möglichkeiten ein multidimensionales Array an eine "Routine" (Funktion??) zu übergeben.



  • Vielen Dank ja die Lösung ist sehr elegant wie gesagt beim Vector bin ich nicht werd versuchen das Ganze trotzdem nachzuvollziehen. Vielen Dank sword dass du dir die Mühe gemacht hast.



  • @Swordfish sagte in Anfängerfrage zu mehrdimensionalen Arrays:

    > std::vector<double> column_sums(rows);
    

    Ich denke, dass sollte besser:

    std::vector<double> column_sums(columns);
    

    heißen.



  • @Belli Danke Belli! 👍



  • @Th69 sagte in Anfängerfrage zu mehrdimensionalen Arrays:

    Du greifst aber mittels M[j][i] zu - und nicht mittels M[i][j]!

    Woher kommt eigentlich die Unsitte solchen Indizes single-letter Namen zu geben? Und dann noch welche die sich zum Verwechseln ähnlich sehen? Ich komm' doch schon bei row und col durcheinander. Sollte eigentlich verboten werden.



  • Tatsächlich. Gute Frage.

    Wahrscheinlich aus BASIC-Zeiten? Wo der Interpreter nur einstellige Variablennamen verstand? Aber soweit ich mich erinnere, waren i, j, k, l, m, n etc. schon immer Zähl-Variablen?



  • @zeropage Ja, schön ... historisch bedingt. Aber wo ist heutzutage der Wert darin sowas zu verbreiten? Vor allem in einem Beispiel wo row und column einfach auch soviel naheliegender ist.



  • Ich schätze, das kommt dann mit der Zeit. Anfangs lernt man halt die Historie, später, wenn man es verstanden hat, gibt man aussagekräftigere Namen.


Anmelden zum Antworten