← Zurück zur Übersicht

Vorlesung 8

Strukturen - Teil 1: Grundlagen

Fortgeschrittene Algorithmen und Programmierung in C

Wie kann man zusammengehörige Daten gruppieren?

Übersicht: Teil 1 (Grundlagen)

  • Motivation: Warum Strukturen?
  • Was ist eine Struktur?
  • Strukturen definieren
  • Struktur-Variablen erstellen
  • Zugriff mit dem Punkt-Operator
  • Strukturen initialisieren
  • Strukturen einlesen und ausgeben
  • Strukturen zuweisen und kopieren
  • Übungsaufgaben

Motivation: Das Problem

Stellen Sie sich vor, Sie möchten Informationen über eine Person speichern:

/* Ohne Strukturen: Jede Information in eigener Variable */ char name[50]; // Name der Person int alter; // Alter der Person double groesse; // Größe in Metern

⚠️ Probleme:

  • Drei separate Variablen für eine Person
  • Keine logische Gruppierung
  • Was ist mit 10 Personen? 100 Personen?

Die Lösung: Strukturen (struct)

Mit einer Struktur fassen wir alles zusammen:

/* Mit Struktur: Alles gehört zusammen! */ struct Person { char name[50]; // Name der Person int alter; // Alter der Person double groesse; // Größe in Metern }; /* Jetzt eine Person-Variable erstellen */ struct Person person1; // Eine komplette Person!

✅ Vorteile:

  • Alle Daten in einer Variable
  • Logische Gruppierung klar erkennbar
  • Übersichtlicher Code

Was ist eine Struktur?

Definition

Eine Struktur (struct) ist ein benutzerdefinierter Datentyp, der mehrere Variablen unterschiedlichen Typs zu einer logischen Einheit zusammenfasst.

Wichtige Begriffe:

  • Struktur-Typ: Die Definition (struct Person)
  • Komponenten/Felder: Die einzelnen Variablen (name, alter, groesse)
  • Struktur-Variable: Eine konkrete Variable (person1)

Syntax: Struktur definieren

So definiert man eine Struktur in C:

/* Allgemeine Syntax */ struct Strukturname { Datentyp komponente1; Datentyp komponente2; /* ... weitere Komponenten ... */ }; // ← Semikolon am Ende!

⚠️ Wichtig: Das Semikolon nach der schließenden Klammer nicht vergessen!

/* Beispiel: Artikel */ struct Artikel { char bezeichnung[50]; int anzahl; double preis; };

Wo definiert man Strukturen?

Struktur-Definitionen stehen vor der main()-Funktion:

#include <stdio.h> /* Struktur-Definition: HIER, vor main() */ struct Person { char name[50]; int alter; double groesse; }; int main() { struct Person p1; // Jetzt verwendbar return 0; }

Die Struktur muss bekannt sein, bevor wir sie verwenden.

Struktur-Variablen erstellen

/* Nach der Definition können wir Variablen erstellen */ struct Person { char name[50]; int alter; double groesse; }; int main() { /* Variablen vom Typ 'struct Person' */ struct Person person1; struct Person person2; struct Person mitarbeiter; /* Jede Variable hat eigene Kopien */ return 0; }

struct Person ist der Typ-Name (wie int), person1 ist der Variablen-Name.

Wie sieht das im Speicher aus?

struct Person person1;

Speicher-Layout von person1:

person1.name: [][][]...[][][] (50 Bytes)
person1.alter: [____] (4 Bytes)
person1.groesse: [________] (8 Bytes)

→ Gesamt: ca. 62 Bytes

Alle Daten liegen direkt hintereinander im Speicher!

Zugriff mit dem Punkt-Operator

Der Punkt-Operator (.) greift auf Komponenten zu:

struct Person person1; /* Zugriff auf Komponenten */ person1.alter = 25; // Schreiben person1.groesse = 1.75; // Schreiben int a = person1.alter; // Lesen double g = person1.groesse; // Lesen

Syntax: variablenname.komponentenname

Wird gelesen als: "die Komponente X der Variable Y"

Zugriff auf String-Komponenten

#include <string.h> // Für strcpy() struct Person { char name[50]; int alter; }; int main() { struct Person p1; /* FALSCH: */ // p1.name = "Anna"; ← Compilerfehler! /* RICHTIG: */ strcpy(p1.name, "Anna"); p1.alter = 23; return 0; }

Arrays können nicht direkt mit = zugewiesen werden. Nutzen Sie strcpy()!

Vollständiges Beispiel

#include <stdio.h> #include <string.h> struct Person { char name[50]; int alter; double groesse; }; int main() { struct Person person1; strcpy(person1.name, "Max Mustermann"); person1.alter = 28; person1.groesse = 1.82; printf("Name: %s\n", person1.name); printf("Alter: %d Jahre\n", person1.alter); printf("Größe: %.2f m\n", person1.groesse); return 0; }

Strukturen initialisieren

Strukturen können direkt initialisiert werden:

struct Person { char name[50]; int alter; double groesse; }; /* Initialisierung mit geschweiften Klammern */ struct Person p1 = {"Anna", 25, 1.68}; // Reihenfolge: name, alter, groesse /* Schrittweise Zuweisung */ struct Person p2; strcpy(p2.name, "Tom"); p2.alter = 30; p2.groesse = 1.75;

Teilweise Initialisierung

struct Person { char name[50]; int alter; double groesse; }; /* Nur erste Werte angeben */ struct Person p1 = {"Lisa", 22}; // groesse wird automatisch 0.0 /* Alle mit 0 initialisieren */ struct Person p2 = {0};

Fehlende Werte werden automatisch mit 0 bzw. "" initialisiert.

Ohne Initialisierung: Zufallswerte! Nutzen Sie = {0}.

Strukturen einlesen

struct Person { char name[50]; int alter; double groesse; }; int main() { struct Person p; printf("Name: "); scanf("%s", p.name); // String: kein & printf("Alter: "); scanf("%d", &p.alter); // int: mit & printf("Größe: "); scanf("%lf", &p.groesse); // double: mit & return 0; }

Bei Strings: kein &. Bei int/double: mit &.

Strukturen zuweisen

Komplette Strukturen können mit = kopiert werden:

struct Person person1 = {"Max", 30, 1.80}; struct Person person2; /* Alle Komponenten kopieren */ person2 = person1; printf("%s, %d Jahre\n", person2.name, person2.alter);

C kopiert automatisch alle Komponenten!

Zuweisung = Kopie

Die Zuweisung erstellt eine Kopie:

struct Person person1 = {"Anna", 25, 1.68}; struct Person person2; person2 = person1; // Kopie! person2.alter = 30; // Nur person2 ändert sich printf("%d\n", person1.alter); // 25 printf("%d\n", person2.alter); // 30

Die Variablen sind unabhängig voneinander!

Strukturen vergleichen (geht NICHT)

struct Person p1 = {"Max", 30, 1.80}; struct Person p2 = {"Max", 30, 1.80}; /* FUNKTIONIERT NICHT! */ // if (p1 == p2) { ... } ← Fehler! /* RICHTIG: Komponenten einzeln */ if (strcmp(p1.name, p2.name) == 0 && p1.alter == p2.alter && p1.groesse == p2.groesse) { printf("Gleich\n"); }

C weiß nicht, wie Strukturen zu vergleichen sind. Vergleichen Sie die Komponenten einzeln!

Mehrere verschiedene Strukturen

/* Erste Struktur */ struct Person { char name[50]; int alter; }; /* Zweite Struktur */ struct Artikel { char bezeichnung[50]; double preis; int anzahl; }; int main() { struct Person kunde = {"Lisa", 28}; struct Artikel produkt = {"Laptop", 899.99, 5}; return 0; }

Häufige Fehler - Teil 1

Fehler 1: Semikolon vergessen

/* FALSCH */ struct Person { char name[50]; } ← Fehlt! /* RICHTIG */ struct Person { char name[50]; };

Fehler 2: "struct" vergessen

/* FALSCH */ Person p1; /* RICHTIG */ struct Person p1;

Häufige Fehler - Teil 2

Fehler 3: String ohne strcpy()

/* FALSCH */ p.name = "Anna"; /* RICHTIG */ strcpy(p.name, "Anna");

Fehler 4: & bei scanf() verwechseln

/* FALSCH */ scanf("%s", &p.name); scanf("%d", p.alter); /* RICHTIG */ scanf("%s", p.name); scanf("%d", &p.alter);

📝 Übungsaufgabe 1: Auto-Struktur

Aufgabe:

Erstellen Sie eine Struktur Auto mit: marke (String), modell (String), baujahr (int), preis (double). Füllen Sie sie mit Daten und geben Sie alles aus.

Denken Sie kurz nach, wie Sie das lösen würden...

✅ Lösung Aufgabe 1

#include <stdio.h> #include <string.h> struct Auto { char marke[50]; char modell[50]; int baujahr; double preis; }; int main() { struct Auto meinAuto; // Daten füllen strcpy(meinAuto.marke, "BMW"); strcpy(meinAuto.modell, "X5"); meinAuto.baujahr = 2023; meinAuto.preis = 65000.00; // Ausgabe printf("Marke: %s\n", meinAuto.marke); printf("Modell: %s\n", meinAuto.modell); printf("Baujahr: %d\n", meinAuto.baujahr); printf("Preis: %.2f Euro\n", meinAuto.preis); return 0; }

💡 Erklärung Aufgabe 1

Wichtige Punkte:

  • Struktur vor main(): Die struct Auto Definition muss vor main() stehen
  • strcpy() für Strings: #include <string.h> ist nötig, und wir verwenden strcpy() für marke und modell
  • Direkte Zuweisung für Zahlen: baujahr und preis können direkt mit = zugewiesen werden
  • Formatierte Ausgabe: %s für Strings, %d für int, %.2f für double mit 2 Dezimalstellen

📝 Übungsaufgabe 2: Adresse einlesen

Aufgabe:

Erstellen Sie eine Struktur Adresse mit: strasse (String), hausnummer (int), plz (int), stadt (String). Lesen Sie die Daten vom Benutzer mit scanf() ein und geben Sie sie formatiert aus.

Überlegen Sie: Wann brauchen Sie & bei scanf()?

✅ Lösung Aufgabe 2

#include <stdio.h> struct Adresse { char strasse[100]; int hausnummer; int plz; char stadt[50]; }; int main() { struct Adresse adresse; // Eingabe printf("Straße: "); scanf("%s", adresse.strasse); // OHNE & printf("Hausnummer: "); scanf("%d", &adresse.hausnummer); // MIT & printf("PLZ: "); scanf("%d", &adresse.plz); // MIT & printf("Stadt: "); scanf("%s", adresse.stadt); // OHNE & // Formatierte Ausgabe printf("\n=== Ihre Adresse ===\n"); printf("%s %d\n", adresse.strasse, adresse.hausnummer); printf("%d %s\n", adresse.plz, adresse.stadt); return 0; }

💡 Erklärung Aufgabe 2

scanf() Regel beachten:

  • Strings (Arrays): scanf("%s", adresse.strasse) - OHNE &
    • Arrays sind bereits Adressen!
  • Primitive Typen (int, double): scanf("%d", &adresse.hausnummer) - MIT &
    • Wir brauchen die Adresse der Variable

Häufiger Fehler: scanf("%s", &adresse.strasse) ist FALSCH!

📝 Übungsaufgabe 3: Kopieren und Ändern

Aufgabe:

Erstellen Sie eine Struktur Produkt mit: name (String) und preis (double). Erstellen Sie p1 mit beliebigen Werten. Kopieren Sie p1 nach p2. Erhöhen Sie den Preis von p2 um 10%. Geben Sie beide aus und zeigen Sie, dass p1 unverändert bleibt.

Wie kopiert man Strukturen?

✅ Lösung Aufgabe 3

#include <stdio.h> #include <string.h> struct Produkt { char name[50]; double preis; }; int main() { struct Produkt p1; // p1 initialisieren strcpy(p1.name, "Laptop"); p1.preis = 1000.00; // p1 nach p2 kopieren struct Produkt p2 = p1; // KOPIE! // Preis von p2 um 10% erhöhen p2.preis = p2.preis * 1.1; // Ausgabe beider Produkte printf("Produkt 1: %s, %.2f Euro\n", p1.name, p1.preis); printf("Produkt 2: %s, %.2f Euro\n", p2.name, p2.preis); printf("\np1 ist unverändert bei %.2f Euro!\n", p1.preis); return 0; }

💡 Erklärung Aufgabe 3

Wichtige Konzepte:

  • Strukturen kopieren mit =: struct Produkt p2 = p1;
    • Kopiert alle Komponenten von p1 nach p2
    • p2 ist eine unabhängige Kopie
  • Änderungen betreffen nur die Kopie:
    • p2.preis = p2.preis * 1.1; ändert nur p2
    • p1 bleibt bei 1000.00 Euro
  • Ausgabe zeigt: p1.preis = 1000.00, p2.preis = 1100.00

📚 Zusammenfassung Übungen

Was haben wir geübt?

  • Aufgabe 1: Struktur definieren, Daten zuweisen, ausgeben
  • Aufgabe 2: Benutzereingabe mit scanf(), & richtig verwenden
  • Aufgabe 3: Strukturen kopieren, unabhängige Änderungen

Nächste Schritte: Üben Sie selbst mit eigenen Strukturen! Probieren Sie verschiedene Datentypen aus.

Zusammenfassung: Teil 1

Was Sie jetzt können:

  • ✅ Strukturen mit struct definieren
  • ✅ Variablen vom Struktur-Typ erstellen
  • ✅ Mit dem Punkt-Operator auf Komponenten zugreifen
  • ✅ Strukturen initialisieren
  • ✅ Strukturen einlesen und ausgeben
  • ✅ Strukturen kopieren mit =

Kernkonzept: Strukturen gruppieren zusammengehörige Daten!

Ende Teil 1

Das Wichtigste beherrschen Sie nun!

Üben Sie mit den drei Übungsaufgaben.
Probieren Sie eigene Strukturen aus!

Vorlesung 9 behandelt fortgeschrittene Themen
(Arrays von Strukturen, Funktionen, Zeiger)

1 / 25