Programmieren mit C


Inhalt


Willkommen

Installation

Das Terminal

Exkurs: Scanf und Sonderzeichen

Exkurs: continue & break

Statische Arrays

Exkurs: sizeof

Arrays: sizeof() und Matrizen

sizeof()

Matrizen

Dynamische Arrays

Exkurs: Speicherbereiche

Funktionen

Exkurs: Funktionen & Arrays

Kommandozeilenparameter

Structs

Dateien

Anwendung: Textdatei einlesen

Hintergrund: Unicode

Stringbibliothek

Ausblick

Light Mode

Exkurs: sizeof

Arrays: sizeof() und Matrizen

In der letzten Vorlesung haben wir uns mit statischen Arrays in C beschäftigt. Oft verwirrend ist hier die Nutzung der eingebauten sizeof-Funktion und die Konstruktion von Matrizen.

sizeof()

Beschäftigen wir uns zunächst mit der Funktion sizeof. Diese gibt uns die Größe eines statischen Arrays zurück. Hier gibt es jedoch einige Besonderheiten zu beachten, wie das folgende Beispiel zeigt.

int    iarr[] = { 1, 2, 3 };
char   carr[] = { 'a', 'b', 'c' };
double darr[] = { 1.0, 2.0, 3.0 };

printf("iarr: %d\ncarr: %d\ndarr: %d\n", 
        sizeof(iarr), sizeof(carr), sizeof(darr));

Führen wir das obige Programm aus, erhalten wir diese Ausgabe.

iarr: 12
carr: 3
darr: 24

Obwohl alle Arrays die gleiche Anzahl an Elementen hat, werden verschiedene Größen zurückgegeben.

Die Erklärung: sizeof gibt die Größe eines Objekts im Speicher in Byte zurück. Ein Integer nimmt 4 Bytes im Speicher ein, damit nehmen drei Integer 4 * 3 = 12 Bytes ein. Ein Character nimmt 1 Byte ein, drei also 3 Bytes. Ein double nimmt 8 Bytes ein, drei doubles also 8 * 3 = 24 Bytes.

Wollen wir stattdessen die Anzahl der Elemente eines Arrays, müssen wir den Rückgabewert von sizeof also noch durch die Speichergröße eines Elementes teilen.

printf("iarr: %d\n", sizeof(iarr)/sizeof(*iarr));

printf("carr: %d\n", sizeof(carr)/sizeof(*carr));

printf("darr: %d\n", sizeof(darr)/sizeof(*darr));

Die Ausgabe ändert sich damit zu

iarr: 3
carr: 3
darr: 3

Schauen wir uns eine Zeile genauer an.

sizeof( iarr ) / sizeof( *iarr )

Die linke Seite ist bekannt, die oben besprochene Speichergröße des ganzen Arrays: 12. Die rechte Seite dereferenziert den Pointer iarr. Wir bekommen also das erste Element des Arrays, den Integer 1. Wenden wir sizeof dann auf diesen Integer an, so bekommen wir eben die Größe, die dieser Datentyp im Speicher einnimmt, also 4.

sizeof( iarr ) / sizeof( *iarr )
       12      /       4           =  3

Matrizen

Wir haben in der Vorlesung zwei Möglichkeiten kennengelernt eine Matrix zu speichern.

Ein eindimensionales Array anlegen und die Indizes ausrechnen Ein mehrdimensionales Array benutzen In C haben die mehrdimensionalen Arrays einige Nachteile und Stolpersteine, ich würde also immer die Nutzung eines eindimensionalen Arrays empfehlen. Da aber beide Varianten in der Wildnis genutzt werden, behandeln wir sie hier auch.

Nehmen wir an, wir wollen eine 2x2 Matrix mit den Einträgen

1 2
3 4

erstellen. Für unser 1D-Array nutzen wir hierzu folgenden Code.

int 1d_arr[] = { 1, 2, 3, 4 };

Beim 2D-Array gibt es einige Sachen zu beachten. Wir benutzen zwei verschachtelte Arrays, bei denen nur in der ersten Dimension die Größe automatisch ermittelt werden kann.

int 2d_arr[][2] = { { 1, 2 }, { 3, 4 } };

Wollen wir das 1D-Array nun ausgeben, könnte der Code so aussehen.

for(int i=0; i<2; ++i) {                                              
    for(int j=0; j<2; ++j) {
        printf("%d ", arr_1d[j+2*i]);
    }
    printf("\n");
}

Wir nutzen zwei Schleifen, um Reihen und Spalten durchzulaufen. Der innere Index j soll hierbei die Spalten einer Reihe abgehen, der äußere Index i die Reihen. Es ergibt sich folgende Iterationsreihenfolge:

i=0, j=0 --> i=0, j=1 --> i=1, j=0 --> i=1, j=1

Da jede Reihe zwei Spalten beinhaltet, müssen wir diese Anzahl im Array weiter springen, um zur nächsten Reihe zu kommen. Im Speicherbild:

Index:  | 0 | 1 || 2 | 3 |
        -----------------
Inhalt: | 1 | 2 || 3 | 4 |

In den ersten beiden Iterationen wollen wir Index 0 und 1 lesen. Die Spalten werden durch unseren inneren Index j abgegangen, der in diesem Beispiel 0 und 1 durchläuft. Durch den Befehl arr_1d[j] haben wir die erste Zeile also geschafft. Danach schaltet unser äußerer Index i auf den Wert 1, wir wollen also die zweite Zeile lesen. Diese beginnt bei Index 2. Damit ergänzen wir den Befehl zu arr_1d[j + 2*i] und können so die ganze Matrix lesen.

Durch die Leerzeile nach der inneren Schleife, bekommen wir als Ausgabe:

1 2
3 4

Benutzen wir das 2D-Array, gestaltet sich dieser Teil etwas einfacher.

for(int i=0; i<2; ++i) {
    for(int j=0; j<2; ++j) {
        printf("%d ", arr_2d[i][j]);
    }
    printf("\n");
}