Übungspaket 23 Mehrdimensionale Arrays Übungsziele: Skript: Deklaration und Verwendung mehrdimensionaler Arrays Kapitel: 49 Semester: Wintersemester 2016/17 Betreuer: Kevin, Matthias, Thomas und Ralf Synopsis: Bevor wir mit komplizierteren Themen wie Zeichenketten weiter machen, müssen wir noch eben eine kleine Übung zu mehrdimensionalen Arrays nachschieben. Mehrdimensionale Arrays sind eine einfache Erweiterung der eindimensionalen Arrays und eigentlich jedem aus der Mathematik als Matrizen bekannt. Insofern erwarten wir keine wesentlichen Probleme ;-)
Teil I: Stoffwiederholung Aufgabe 1: Wiederholung eindimensionaler Arrays Aus welchen Komponennten besteht eine Array-Definition (ohne Initialisierung)? 1. 2. 3. 4. Welche Indizes sind gültig, wenn wir ein Array der Größe n (z.b. 14) haben? Aufgabe 2: Aufbau mehrdimensionaler Arrays Wie werden die einzelnen Dimensionen eines mehrdimensionalen Arrays definiert? Wie wird auf die einzelnen Elemente eines mehrdimensionalen Arrays zugegriffen? Wie werden die Elemente eines mehrdimensionalen Arrays in der Programmiersprache C im Arbeitsspeicher abgelegt? Aufgabe 3: Speicherbelegung am Beispiel Nehmen wir an, wir hätten folgende Matrize: A = ( a11 a 12 a 13 a 21 a 22 a 23 ) Wie kann eine derartige Matrize in C umgesetzt werden? Welche Indizes sind gültig? In welcher Reihenfolge werdne die einzelnen Elemente im Arbeitsspeicher abgelegt? Wie werden die Parameter a ij im Speicher angeordnet? Einführung in die Praktische Informatik, Wintersemester 2016/17 23-1
Teil II: Quiz Aufgabe 1: Definition mehrdimensionaler Arrays In der folgenden Tabelle sind einige Definitionen vorgegeben. Das erste Beispiel ist bereits vorgegeben; vervollständige die freien Spalten: Definition Dimensionen Größe in Bytes gültige Indizes char c[2][4][2]...3...16 (0..1) (0..3) (0..1) char c[3][3]..................................................................................... char c[2][2][2][2]..................................................................................... char c[1][2][1]..................................................................................... char c[ z - a ][2]..................................................................................... char c[ z - a ][1]................................................................................................................................................................. (0..2) (0..6) (0..1) (0..2) Aufgabe 2: Implizit definierte Arrays Die Größe eines Arrays kann man auch implizit durch eine zusätzliche Initialisierung definieren. Gegeben seien die folgenden drei Definitionen: 1. int a[][] = {{0, 1, 2}, {3, 4, 5}}; 2. int b[][ 2 ] = {{0, 1}, {2, 3}, {4, 5}}; 3. int c[][ 2 ] = {0, 1, 2, 3, 4, 5}; Vervollständige die folgende Tabelle: Array explizite Definition a................................. b................................. c................................. 23-2 Wintersemester 2016/17, Einführung in die Praktische Informatik
Teil III: Fehlersuche Aufgabe 1: Arbeiten mit mehreren Zahlen Die folgenden Programmzeilen bewirken nichts sinnvolles, sondern dienen lediglich dem Einüben mehrdimensionaler Arrays. Doch auch hier hat Freizeitwindsurfer Dr. Surf ein paar kleine Fehler gemacht. Finde, beschreibe und korrigiere diese. 1 int i; 2 int a[ 2, 3, 4 ]; 3 int b[ 3 ][4 ; 5 ]; 4 int c[ 2 ][ 2 ]; 5 i = a[ 1, 1, 1 ]; 6 i = b[ 3 ][ 4 ][ 5 ]; 7 i = c[ 1 ][ 1 ][ 1 ]; Einführung in die Praktische Informatik, Wintersemester 2016/17 23-3
Teil IV: Anwendungen In den ersten drei Aufgaben üben wir das Definieren und Initialisieren mehrdimensionaler Arrays. Anschließend diskutieren wir, wie mehrdimensionale Matrizen als Parameter an Funktionen übergeben werden können. Den Abschluss bildet eine kleine Anwendung. Aufgabe 1: Deklaration mehrdimensionaler Arrays Vervollständige in der folgenden Tabelle die fehlenden Definitionen: Elementtyp Größe Deklaration int 3 2 4..................................................... char 2 10..................................................... double 4 1 5 2..................................................... Aufgabe 2: Implizit definierte Arrays 1. Definiere ein zweidimensionales Array mit zwei Zeilen à drei Spalten, in denen die Zahlen 1, 2, 3, 4, 5 und 6 stehen: 2. Definiere ein zweidimensionales Array mit drei Zeilen à zwei Spalten, in denen der Reihe nach die Buchstaben a bis f stehen: 3. Definiere ein Array mit drei Zeilen à drei Spalten, in denen Zahlen 1.0 stehen: Aufgabe 3: Zugriff auf mehrdimensionale Arrays 1. Entwickle ein kleines Programm, das eine 3 3-Matrix definiert und wie folgt initialisiert: Die Diagonalelemente sollen als Wert die Zeilennummer erhalten, alle anderen den Wert Null. Zur Eigenkontrolle soll das Programm diese Matrix ausgeben. Beispiel: 1 0 0 0 2 0 0 0 3 23-4 Wintersemester 2016/17, Einführung in die Praktische Informatik
2. Schreibe ein Programm, das eine 4 1 2 1-Matrix definiert, in der alle Elemente den Wert 1.0 haben. Zur Eigenkontrolle soll das Programm diese Matrix ausgeben. Einführung in die Praktische Informatik, Wintersemester 2016/17 23-5
Aufgabe 4: Mehrdimensionale Arrays als Parameter Mehrdimensionale Arrays können in ihrer generischen Form leider nicht so einfach als Parameter an Funktionen übergeben werden, wie wir dies bei eindimensionalen Parametern kennengelernt haben. Bevor du weiter liest, überlege dir zunächst wie dies bei eindimensionalen Arrays war und warum es bei mehrdimensionalen Arrays nicht so direkt geht. Gegeben sei die Definition: char c[ 3 ][ 3 ]. Vervollständige folgende Tabelle: Ausdruck Resultat Ausdruck Resultat sizeof(c[ 1 ][ 0 ])............. sizeof(c[ 0 ][ 0 ])............. sizeof(c[ 4 ][ 5 ])............. sizeof(c[ 0 ])............. sizeof(c[ 1 ])............. sizeof(c)............. Gegeben sei nun folgendes Programm: 1 # include <stdio.h> 2 3 char f( char m [][], int size ) 4 { 5 } 6 7 int main ( int argc, char ** argv ) 8 { 9 char c[ 3 ][ 3 ]; 10 f( c, 9 ); 11 } Hierzu haben wir nun folgende Fragen: Ist die Syntax dieses Programms korrekt? Falls nein, welche Zeilen sind problematisch? Falls nein, worin liegt das Problem? Welchen Typ hat der Parameter c? 23-6 Wintersemester 2016/17, Einführung in die Praktische Informatik
Was wird der Compiler anmeckern und was bzw. wie können wir das Problem beheben? Eine interessante Frage bleibt nun, ob wir nicht dennoch eine Funktion schreiben können, die beliebige quadratische Matrizen initialisieren kann? Die Antwort ist recht einfach: Wir wissen, wie auch ein mehrdimensionales Array im Arbeitsspeicher abgelegt wird und wir wissen, wie wir das erste Element eines beliebigen Arrays erhalten. Um beides zusammenzubringen, können wir innerhalb der Funktion ein eindimensionales Array betrachten, das wir durch eigene Berechnungen rekonstruieren. Lange Rede kurzer Sinn, hier kommt ein kleines Beispiel zur Initialisierung von n n-diagonalmatritzen: 1 # include <stdio.h> 2 3 void dig_ init ( int * p, int n ) 4 { 5 int i, j; 6 for ( i = 0; i < n; i ++ ) 7 for ( j = 0; j < n; j ++ ) 8 p[ i + j * n ] = (i == j)? 1: 0; 9 } 10 11 int main ( int argc, char ** argv ) 12 { 13 # define SIZE 3 14 int a[ SIZE ][ SIZE ]; 15 int i, j; 16 dig_init ( & a[ 0 ][ 0 ], SIZE ); 17 for ( i = 0; i < SIZE ; i ++ ) 18 { 19 for ( j = 0; j < SIZE ; j ++ ) 20 printf ( "%d ", a[ i ][ j ] ); 21 printf ( "\n" ); 22 } 23 } Einführung in die Praktische Informatik, Wintersemester 2016/17 23-7
Aufgabe 5: Matrixmultiplikation Als kleine Zusatz- bzw. Abschlussaufgabe beschäftigen wir uns mit der Multiplikation einer Matrix mit einem Vektor. 1. Vorbetrachtungen In der Mathematik ist das Resultat R der Multiplikation einer Matrix A mit einem Vektor V wie folgt definiert: 2. Aufgabenstellung 1 a 11... a 1m A =..... a n1... a nm, V = v 1. v m, R = R = A V mit m r i = a ik r k i=k Entwickle eine Funktion mat mul(), die eine n m Matrix A mit einem Vektor V der Länge m multipliziert und das Ergebnnis in einem Vektor R der Länge n ablegt. In der ersten Variante soll die Funktion mat mul() wissen, dass die Zeilenlänge der Matrix A genau m ist. Als Elementtyp soll double verwendet werden. 3. Pflichtenheft: Aufgabe, Eingabe, Ausgabe, Sonderfälle, Funktionskopf r 1. r n 4. Testdaten Zum Test unseres Programm können wir das folgende Beispiel verwenden: R = 5. Implementierung r 1 r 2 r 3 = 1.0 0.0 0.0 1.0 1.0 0.0 1.0 1.0 1.0 1.0 2.0 3.0 = Da wir die einzelnen Definitionen und Algorithmen bereits besprochen haben, können wir gleich mit der Kodierung fortfahren. 23-8 Wintersemester 2016/17, Einführung in die Praktische Informatik 1.0 3.0 6.0
6. Kodierung Unsere beispielhafte Kodierung sieht wie folgt aus: Einführung in die Praktische Informatik, Wintersemester 2016/17 23-9
7. Aufgabenstellung 2 Das Ziel dieser letzten Teilaufgabe ist es, die Funktionen mat mul() und prt mat() so umzuschreiben, dass sie für beliebige zweidimensionale Matrizen funktionieren. Dabei können wir auf die Ergebnisse der Aufgabe 4 zurückgreifen, die bereits diskutiert hat, wie mittels der Größenparameter die zweidimensionale Struktur einer Matrize rekonstruiert werden kann. 8. Pflichtenheft: Aufgabe, Funktionskopf 9. Testdaten Zum Test unseres Programm können wir wieder das folgende Beispiel verwenden: R = 10. Implementierung r 1 r 2 r 3 = 1.0 0.0 0.0 1.0 1.0 0.0 1.0 1.0 1.0 1.0 2.0 3.0 = Da wir die einzelnen Definitionen und Algorithmen bereits besprochen haben, können wir gleich mit der Kodierung fortfahren. Die bestehende Implementierung müssen wir nur um die korrekte Adressberechnung erweitern. 1.0 3.0 6.0 23-10 Wintersemester 2016/17, Einführung in die Praktische Informatik
11. Kodierung Unsere beispielhafte Kodierung sieht wie folgt aus: Einführung in die Praktische Informatik, Wintersemester 2016/17 23-11