Ubungspaket 23 ¨
Mehrdimensionale Arrays
Ubungsziele: ¨
Deklaration und Verwendung mehrdimensionaler Arrays Skript:
Kapitel: 49 Semester:
Wintersemester 2021/22 Betreuer:
Thomas, Tim und Ralf Synopsis:
Bevor wir mit komplizierteren Themen wie Zeichenketten weiter ma- chen, m¨ ussen wir noch
” eben“ eine kleine ¨ Ubung zu mehrdimensionalen
Arrays nachschieben. Mehrdimensionale Arrays sind eine einfache Er-
weiterung der eindimensionalen Arrays und eigentlich jedem aus der
Mathematik als Matrizen bekannt. Insofern erwarten wir keine wesent-
lichen 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¨ultig, wenn wir ein Array der Gr¨oß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¨atten folgende Matrize: A= a11 a12 a13 a21 a22 a23
!
Wie kann eine derartige Matrize in C umgesetzt werden?
Welche Indizes sind g¨ultig?
In welcher Reihenfolge werdne die einzelnen Elemente im Arbeitsspeicher abgelegt?
Wie werden die Parameteraij im Speicher angeordnet?
Teil II: Quiz
Aufgabe 1: Definition mehrdimensionaler Arrays
In der folgenden Tabelle sind einige Definitionen vorgegeben. Das erste Beispiel ist bereits vorgegeben; vervollst¨andige die freien Spalten:
Definition Dimensionen Gr¨oße in Bytes g¨ultige 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¨oße eines Arrays kann man auch
”implizit“ durch eine zus¨atzliche 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¨andige die folgende Tabelle:
Array
”explizite“ Definition a . . . .
b . . . .
c . . . .
Teil III: Fehlersuche
Aufgabe 1: Arbeiten mit mehreren Zahlen
Die folgenden Programmzeilen bewirken nichts sinnvolles, sondern dienen lediglich dem Ein¨uben mehrdimensionaler Arrays. Doch auch hier hat FreizeitwindsurferDr. 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 ];
Teil IV: Anwendungen
In den ersten drei Aufgaben ¨uben wir das Definieren und Initialisieren mehrdimensionaler Arrays. Anschließend diskutieren wir, wie mehrdimensionale Matrizen als Parameter an Funktionen ¨ubergeben werden k¨onnen. Den Abschluss bildet eine kleine Anwendung.
Aufgabe 1: Deklaration mehrdimensionaler Arrays
Vervollst¨andige in der folgenden Tabelle die fehlenden Definitionen:
Elementtyp Gr¨oß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 `a drei Spalten, in denen die Zahlen1,2,3,4,5 und 6 stehen:
2. Definiere ein zweidimensionales Array mit drei Zeilen `a zwei Spalten, in denen der Reihe nach die Buchstaben a bis f stehen:
3. Definiere ein Array mit drei Zeilen `a drei Spalten, in denen ¨uberall die Zahl1.0steht:
Aufgabe 3: Zugriff auf mehrdimensionale Arrays
1. Entwickle ein kleines Programm, das eine3×3-Matrix definiert und wie folgt initiali- siert: 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
2. Schreibe ein Programm, das eine 4×1×2×1-Matrix definiert, in der alle Elemente den Wert 1.0haben. Zur Eigenkontrolle soll das Programm diese Matrix ausgeben.
Aufgabe 4: Mehrdimensionale Arrays als Parameter
Mehrdimensionale Arrays k¨onnen in ihrer generischen Form leider nicht so einfach als Pa- rameter an Funktionen ¨ubergeben werden, wie wir dies bei eindimensionalen Parametern kennengelernt haben. Bevor du weiter liest, ¨uberlege dir zun¨achst wie dies bei eindimen- sionalen Arrays war und warum es bei mehrdimensionalen Arrays nicht so direkt geht.
Gegeben sei die Definition: char c[ 3 ][ 3 ]. Vervollst¨andige folgende Tabelle:
Ausdruck Resultat
sizeof(c[ 1 ][ 0 ]) . . . .
sizeof(c[ 0 ][ 0 ]) . . . .
sizeof(c[ 4 ][ 5 ]) . . . .
Ausdruck Resultat sizeof(c[ 0 ]) . . . .
sizeof(c[ 1 ]) . . . .
sizeof(c) . . . .
Gegeben sei nun folgendes Programm:
1 # i n c l u d e < s t d i o . h >
2
3 c h a r f ( c h a r m [][] , int s i z e )
4 {
5 }
6
7 int m a i n ( int argc , c h a r ** a r g v )
8 {
9 c h a r 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?
Was wird der Compiler anmeckern und was bzw. wie k¨onnen wir das Problem beheben?
Eine interessante Frage bleibt nun, ob wir nicht dennoch eine Funktion schreiben k¨onnen, die beliebigequadratische 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 zusammen- zubringen, k¨onnen 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 # i n c l u d e < s t d i o . h >
2
3 v o i d d i g _ i n i t ( 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 m a i n ( int argc , c h a r ** a r g v )
12 {
13 # d e f i n e S I Z E 3
14 int a [ S I Z E ][ S I Z E ];
15 int i , j ;
16 d i g _ i n i t ( & a [ 0 ][ 0 ] , S I Z E ) ; 17 for ( i = 0; i < S I Z E ; i ++ )
18 {
19 for ( j = 0; j < S I Z E ; j ++ )
20 p r i n t f ( " % d " , a [ i ][ j ] ) ; 21 p r i n t f ( " \ n " ) ;
Aufgabe 5: Matrixmultiplikation
Als kleine Zusatz- bzw. Abschlussaufgabe besch¨aftigen 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:
A=
a11 . . . a1m
... . .. ... an1 . . . anm
, V =
v1
... vm
, R=
r1
... rn
R =A·V mit ri =
m
X
i=k
aikvk
2. Aufgabenstellung 1
Entwickle eine Funktion mat mul(), die eine n×m Matrix A mit einem Vektor V der L¨ange m multipliziert und das Ergebnnis in einem Vektor R der L¨ange n ablegt. In der ersten Variante soll die Funktion mat mul()
”wissen“, dass die Zeilenl¨ange der MatrixA genaum ist. Als Elementtyp soll double verwendet werden.
3. Pflichtenheft: Aufgabe, Eingabe, Ausgabe, Sonderf¨alle, Funktionskopf
4. Testdaten
Zum Test unseres Programm k¨onnen wir das folgende Beispiel verwenden:
R =
r1 r2 r3
=
1.0 0.0 0.0 1.0 1.0 0.0 1.0 1.0 1.0
·
1.0 2.0 3.0
=
1.0 3.0 6.0
5. Implementierung
Da wir die einzelnen Definitionen und Algorithmen bereits besprochen haben, k¨onnen wir gleich mit der Kodierung fortfahren.
6. Kodierung
Unsere beispielhafte Kodierung sieht wie folgt aus:
7. Aufgabenstellung 2
Das Ziel dieser letzten Teilaufgabe ist es, die Funktionenmat mul()undprt mat()so umzuschreiben, dass sie f¨ur beliebige zweidimensionale Matrizen funktionieren. Dabei k¨onnen wir auf die Ergebnisse der Aufgabe 4 zur¨uckgreifen, die bereits diskutiert hat, wie mittels der Gr¨oßenparameter die zweidimensionale Struktur einer Matrize rekonstruiert werden kann.
8. Pflichtenheft: Aufgabe, Funktionskopf
9. Testdaten
Zum Test unseres Programm k¨onnen wir wieder das folgende Beispiel verwenden:
R =
r1 r2 r3
=
1.0 0.0 0.0 1.0 1.0 0.0 1.0 1.0 1.0
·
1.0 2.0 3.0
=
1.0 3.0 6.0
10. Implementierung
Da wir die einzelnen Definitionen und Algorithmen bereits besprochen haben, k¨onnen wir gleich mit der Kodierung fortfahren. Die bestehende Implementierung m¨ussen wir nur um die korrekte Adressberechnung erweitern.
11. Kodierung
Unsere beispielhafte Kodierung sieht wie folgt aus: