C-Vorkurs, Tag 3, 13. April 2016

Inhalte heute

Funktionen, Speicherverwaltung, benutzerdefinierte Datentypen

Globale und lokale Variablen

  • Außerhalb von Funktionen deklarierte Variablen sind global

    • Auf sie kann überall direkt zugegriffen werden

    • Sollte vermieden werden, wenn nicht unbedingt nötig

  • Innerhalb von Funktionen deklarierte Variablen sind lokal

    • Nur innerhalb der Funktion kann direkt auf sie zugegriffen werden
                                char c;
void foo() {                    void foo() {
    c = 'Z';                        c = 'Z';
}                               }
int main() {                    int main() {
    char c = 'A';                   c = 'A';
    foo();                          foo();
}                               }

Rückblick: Funktionen

void swap(int32_t x, int32_t y) {
    int32_t tmp = x;
    x = y;
    y = tmp;
}

int main() {
    int32_t a = 10, b = 20;
    swap(a, b);
    printf("a=%"PRId32", b=%"PRId32"\n", a, b);
    return 0;
}

Was wird ausgegeben?

Rückblick: Funktionen und Zeiger

void swap(int32_t *x, int32_t *y) {
    int32_t tmp = *x;
    *x = *y;
    *y = tmp;
}

int main() {
    int32_t a = 10, b = 20;
    swap(&a, &b);
    printf("a=%"PRId32", b=%"PRId32"\n", a, b);
    return 0;
}

Was wird ausgegeben?

Rückgabe von Arrays

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>

uint8_t *erzeuge_leere_liste(uint8_t len) {
    uint8_t list[len];
    for (uint8_t i = 0; i < len; i++) {
        list[i] = 0;
    }
    return list;
}

int main() {
    uint8_t *tolle_liste = erzeuge_leere_liste(10);
    printf("tolle_liste[7] = %"PRIu8"\n", tolle_liste[7]);

    return 0;
}

Rückgabe von Arrays – malloc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>

uint8_t *erzeuge_leere_liste(uint8_t len) {
    uint8_t *list = (uint8_t*)malloc(sizeof(*list)*len);
    for (uint8_t i = 0; i < len; i++) {
        list[i] = 0;
    }
    return list;
}

int main() {
    uint8_t *tolle_liste = erzeuge_leere_liste(10);
    printf("tolle_liste[7] = %"PRIu8"\n", tolle_liste[7]);
    free(tolle_liste);
    return 0;
}

Rückgabe von Arrays – malloc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>

uint8_t *erzeuge_leere_liste(uint8_t len) {
    uint8_t *list = malloc(sizeof(*list)*len);
    for (uint8_t i = 0; i < len; i++) {
        list[i] = 0;
    }
    return list;
}

int main() {
    uint8_t *tolle_liste = erzeuge_leere_liste(10);
    printf("tolle_liste[7] = %"PRIu8"\n", tolle_liste[7]);
    free(tolle_liste);
    return 0;
}

malloc

  • malloc gibt Zeiger auf Speicher der angefragten Größe zurück

  • auf diesen Speicher kann von überall zugegriffen werden

  • Speicher muss explizit per free freigegeben werden (sonst Speicherleck, keine GC)

Benutzerdefinierte Datenstrukturen

  • Angenommen wir wollen Daten zu einem Auto speichern, beispielsweise

    • Automarke
    • Höchstgeschwindigkeit
    • Farbe
    #define ROT 1
    #define BLAU 2
    #define SCHWARZ 3
    // ...
    char marke[10];
    uint16_t max_geschw;
    uint8_t farbe;

Benutzerdefinierte Datenstrukturen II

  • Jetzt wollen wir mehrere Autos (5) verwalten

  • Mögliche Lösung:

    char marke[5][10];
    uint16_t max_geschw[5];
    uint8_t farbe[5];
  • Nachteil: inhaltlich zusammenhängende Daten nicht zusammen

  • Idee: Wollen ein Konstrukt, das wir als Auto bezeichnen und welches jeweils die drei Eigenschaften beinhaltet

Benutzerdefinierte Datenstrukturen III

  • C bietet dafür sogenannte struct-Datentypen an

    struct Auto {
        char marke[10];
        uint16_t max_geschw;
        uint8_t farbe;
    };
    struct Auto mein_auto = {"Tata", 135, ROT};
    struct Auto dein_auto;
    dein_auto.max_geschw = 80;
    dein_auto.farbe = BLAU;
    strncpy(dein_auto.marke, "Trabi", 10);
    dein_auto.marke[9] = 0;

Benutzerdefinierte Datenstrukturen IV

  • Wie bei Arrays sind structs einfach zusammenhängender Speicher

  • Lokal angelegte struct-Variablen können nicht aus einer Funktion zurückgegeben werden malloc

    struct Auto * neuer_mercedes(uint8_t farbe) {
        struct Auto * neu = malloc(sizeof(struct Auto));
        (*neu).farbe = farbe;  // So könnte man das benutzen
        neu->max_geschw = 250; // So ist es gedacht
        strncpy(neu->marke, "Mercedes", 10);
        neu->marke[9] = 0;
        return neu;
    }

Was haben wir (bisher) heute gelernt?

Was haben wir (bisher) heute gelernt?

  • Gültigkeitsbereich von Variablen

  • Funktionen

  • Speicherverwaltung

  • benutzerdefinierte Datentypen