Vorlesung 12 Flashcards

1
Q

Entwicklung großer Programme

A
  • Bislang: Quellcode in einer einzigen Datei
  • Vorgehensweise gut geeignet für kleine Programme, bei größeren
    Programmen entstehen folgende Probleme:
  • Große Quelldateien sind unübersichtlich und schlecht zu warten
  • Editieren und Compilieren dauert wesentlich länger
  • Eine voneinander unabhängige Arbeit der Teammitglieder ist nur
    schwer möglich
  • Abhilfe: Aufteilung des Programms/Quelltextes in mehrere Dateien/Module
  • Wiederverwendbarkeit (ein Modul in mehreren Programmen)
  • Aufteilung auf mehrere Personen
  • Nur geänderte Module müssen übersetzt werden
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Design-Kriterien für Module

A
  • Module bestehen aus einzelnen Funktionen
  • Hoher Zusammenhang: Die Funktionen eines Moduls sollten inhaltlich
    zusammenhängen
  • Geringe Kopplung: Nur wenige Funktionen sollten zur Kommunikation des
    Moduls nach außen notwendig sein
  • Wiederverwendbarkeit von Modulen
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Kommunikation zwischen Modulen

A

Funktionen und Variablen eines Moduls, die von anderen Programmteilen
benutzt werden, müssen in dem importierenden Modul deklariert werden.
* Deklarationen in Header-Dateien (Dateiendung .h), die mit #include
eingebunden werden.
* Eine Header-Datei enthält:
* #define- und #include-Befehle
* globale und externe Variablen
* Prototypen von globalen und externen Funktionen
* Selbstdefinierte Datentypen

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Funktionsprototypen

A
  • Deklaration einer Funktion mit ihren typisierten Parametern und
    Rückgabewert ohne Funktionsrumpf.
  • Syntax wie Funktionskopf, Abschluss mit Semikolon.
  • Beispiele:
    int quadrat(int x);
    void ausgabe();
  • Funktionsdefinition (Funktionsrumpf) muss später folgen.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Speicherklassen von Funktionen

A
  • Lebensdauer: während des gesamten Programms
  • Sichtbarkeit
  • in allen Quelldateien (keine Angabe)
  • nur in der gleichen Quelldatei (Schlüsselwort static)
  • Statische Funktionen (static) sind eine Ausnahme: Bei komplexen
    Programmen, die aus mehreren Dateien (Modulen) bestehen.
    Hilfsfunktionen, die nur innerhalb eines Moduls benötigt wird. Vermeidung
    von Namenskonflikten.

static void fehlermeldung()
{
printf(“Es ist ein Fehler aufgetreten!\n”);
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Kommandozeilenparameter

A

● Kommandozeilenparameter werden beim Aufruf eines Programms als
Parameter der Funktion main übergeben.
● Vollständige Definition der Funktion main:

int main(int argc, char *argv[])
oder
int main(int argc, char **argv)

  • argc: Anzahl der Argumente (argc ≥ 1)
  • argv: Zeiger auf Array von Zeigern auf Zeichenketten (argv[0] ist der
    Programmaufruf, argv[1] das erste Argument, …, argv[argc-1] das
    letzte Argument)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Kommandozeilenparameter beispiel

A

int main(int argc, char *argv[])
{
int i;
printf(“Programm %s mit %d Parameter(n) gestartet\n”,
argv[0], argc);
for(i = 0; i < argc; i++) {
printf(“Parameter %d: %s\n”, i, argv[i]);
}
}

Programmaufruf (aus Konsole/Eingabeaufforderung) und Ausgabe

> cmd_par toller text
Programm cmd_par mit 3 Parametern gestartet
Parameter 0: ./cmd_par
Parameter 1: toller
Parameter 2: text

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Kommandozeilenparameter weiteres

A

● Eingegebene Zahlen stehen nur als Zeichenkette zur Verfügung
● Umwandeln in Zahl notwendig
● Beispiel mit Bibliotheksfunktion atoi

int main(int argc, char *argv[])
{
int a, b;
if(argc != 3) {
printf(“Programm mit zwei Zahl-Parametern aufrufen!\n”);
return 1;
}
a = atoi(argv[1]);
b = atoi(argv[2]);
printf(“Summe: %d\n”, a + b);

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Zeitfunktionen – Datentypen

A
  • Die Header-Datei time.h bietet verschiedene Funktionen, um Zeit zu erfassen
    und zu messen.
  • Wesentliche Datentypen:
  • clock_t bezeichnet CPU-Zeit
  • time_t Zeitstempel in Sekunden
  • struct tm erfasst einen Zeitpunkt im Kalender
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Zeit ermitteln

A
  • clock_t clock ()
  • liefert die Rechnerkernzeit (Takte) seit Beginn des Programms
  • Konstante CLOCKS_PER_SEC liefert Takte pro Sekunde
  • time_t time (time_t* timer)
  • liefert aktuelle Kalenderzeit (i.d.R. als Sekunden seit dem 1.1.1970 0:00 Uhr).
  • Parameter ist optional. Kann NULL sein.
  • double difftime (time_t end, time_t beginning)
  • Berechnet Differenz zwischen zwei Zeitwerten in Sekunden.
  • time_t mktime (struct tm * timeptr);
  • Wandelt einen Wert in der tm-Struktur in time_t um.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Zeitwerte konvertieren

A
  • char* asctime (const struct tm * timeptr);
  • Konvertiert tm-Strukturwert in lesbare String-Form.
  • struct tm *gmtime (const time_t * timer);
  • Wandelt ein time_t-Objekt in tm-Strukturwert in UTC (Weltzeit) um.
  • struct tm *localtime (const time_t * timer);
  • Wandelt ein time_t-Objekt in tm-Strukturwert in lokaler Zeit um.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Anwendung: Zeit ausgeben

A

include <stdio.h></stdio.h>

#include <time.h>
int main() {
time_t current = time(NULL);</time.h>

const char* str = asctime(localtime(&current));

printf(“Aktuelle Zeit:\n%s”, str);
return 0;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Anwendung: Zeit messen

A

include <stdio.h></stdio.h>

#include <time.h>
void complicatedAlgorithm() {
// do something complicated
}
int main() {
time_t startTime = time(NULL);</time.h>

complicatedAlgorithm();
double diff = difftime(time(NULL), startTime);
printf(“Dauer: %.1f s\n”, diff);
return 0;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Anwendung: Warten

A

include <stdio.h></stdio.h>

#include <time.h>
void waitFor(double secs) {
// Berechne zukünftigen Zeitstempel
clock_t futureTime = clock() + secs * CLOCKS_PER_SEC;</time.h>

// Warte bis Taktzahl erreicht ist
while (clock() < futureTime) { }
}
int main() {
printf(“Erste Ausgabe.\n”);

waitFor(5);

printf(“Zweite Ausgabe nach 5 Sekunden.\n”);
return 0;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Aufruf externer Programme

A

include <stdlib.h></stdlib.h>

Syntax
#include <stdlib.h>
int system(const char *s)
● Bedeutung
* liefert Zeichenkette s an Systemumgebung zur Ausführung
* d.h. mit der Funktion system kann aus einem Programm heraus ein anderes
Programm gestartet werden</stdlib.h>

int main()
{
system(“dir”);
/* system(“ls -l”); UNIX/Linux Version */
return 0;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Programmabbruch

A

● Syntax
#include <stdlib.h>
void abort()
void exit(int status)
int atexit(void (*fcn)(void))
● Bedeutung
* abort und exit beenden das Programm. Bei exit kann ein Rückgabewert an
das Betriebssystem angegeben werden, zudem werden alle Dateien ordentlich
geschlossen und die mit atexit festgelegten Funktionen aufgerufen
* Mit atexit können Funktionen „angemeldet“ werden, die bei einem
Programmende ausgeführt werden sollen, z.B. um Aufräumarbeiten wie Datei
speichern etc. vorzunehmen.</stdlib.h>

17
Q

Zufallszahlen

A

Zufallszahlen: Eine Folge von Zahlen mit zufälligem Wert
● Anwendungsbereiche für Zufallszahlen
* Kryptographie (Schlüsselerzeugung)
* Simulation
* Stichproben (Auswahl aus großer Datenmenge)
* Entscheidungsfindung (z.B. bei Computerspielen)
● Problem: Computer arbeiten deterministisch
* Wie können zufällige Zahlen erzeugt werden?
* Antwort: gar nicht, aber Pseudozufallszahlen

18
Q

Pseudozufallszahlen

A

● Pseudozufallszahlen sollen
* gleichmäßig verteilt sein
* sich möglichst lange nicht wiederholen
● Ein einfaches Verfahren für Zufallszahlen 0 bis m-1: Methode der linearen
Kongruenz (Lehmer, 1951)

a[0] = seed;
for(i = 1; i < n; i++)
a[i] = (a[i-1] * b + 1) % m;

  • Güte abhängig von b und m
  • Für Kryptographie nicht geeignet, da mit geeigneten Analysemethoden
    Parameter aus Zufallsfolge berechenbar und somit vorhersagbar
19
Q

Bibliotheksfunktionen für Zufallszahlen

A

include <stdlib.h></stdlib.h>

  • Funktionen in stdlib.h
  • int rand(): liefert eine Zufallszahl zwischen 0 und der Konstanten RAND_MAX
  • void srand(unsigned int seed): Initialisierung der Zufallszahlenfolge
  • Die time-Funktion ist hilfreich, um bei jedem Programmaufruf einen anderen
    Startwert für den Zufallsgenerator zu setzen.
  • Beispiel: Erzeuge ganzzahlige Zufallszahlen im Intervall [1, 6]

#include <time.h>
...
srand((unsigned) time(NULL));
...
z1 = 1 + rand() % 6;
z2 = 1 + rand() % 6;</time.h>

20
Q

Funktionen mit variabler Parameterliste

A

Bisher: Funktionsdefinition umfasst genaue Anzahl der Parameter und
genauen Typ jedes einzelnen Parameters.
● C erlaubt aber für Funktionen wie printf auch Parameterliste zu
definieren, die beliebig viele Parameter enthalten dürfen.
● Aber Vorsicht: Compiler kann dann keine Prüfung der Parameter vornehmen
(seltsames Verhalten bei unpassenden Variablen / Datentypen bei printf).

● Syntax
– [Speicherklasse] [Typ] Funktionsname ( fester_Parameter, …)
● Beispiel
int printf(const char *format, …)

● Beachte
– am Anfang ist mindestens ein fester Parameter erforderlich
– keine Variablen innerhalb der Funktion für die Parameter vorhanden

21
Q

Funktionen mit variabler Parameterliste
weiteres

A

include <stdio.h></stdio.h>

Auslesen der Parameter mit Makros aus stdarg.h:
* va_list
Datentyp für Parameterliste
* va_start(va_list ap, lastarg)
Initialisierung der Argumentenliste, lastarg ist letzter
benannter Parameter
* va_arg(va_list ap, typ)
nächsten Parameter aus der Liste auslesen
* va_end(va_list ap)
Ende der Parameterbehandlung

#include <stdarg.h>
/* Berechne Mittelwert beliebig vieler double-Zahlen */
double mittelwert(int anz, ...)
{
int i;
double v, summe = 0;
va_list ap;
va_start(ap, anz);
for(i = 0; i < anz; i++) {
v = va_arg(ap, double);
summe += v;
}
va_end(ap);
return summe / anz;
}</stdarg.h>

22
Q

übersichtlichkeit

A

— Bezeichner sollten sinnvolle, erklärende Namen haben.
* Je besser die Bezeichner, desto weniger Code-Kommentare
sind erforderlich.
* Schlecht gewählte Bezeichner erhöhen die Fehlerwahrscheinlichkeit
beträchtlich.

—Variablen
* Sinnvolle Bezeichner verwenden, die den Zweck/Inhalt der
Variablen beschreiben
* Kleinschreibung mit CamelCase:
student, studentList, currentStudent, …
* 1-Buchstaben-Variablen nur für triviale Zählvariablen (i, j, …)

—Strukturtypen, Aufzählungstypen und Unions
* Sinnvolle Bezeichner verwenden, die den Zweck des Typs
beschreiben
* Großschreibung mit CamelCase:
Node, LinkedList, DoubleLinked, List.

—Präprozessor-Direktiven und Makros
Sinnvolle Bezeichner verwenden, die den Zweck/Inhalt der
Variablen beschreiben
* Jeder Buchstabe groß, Trennung durch Unterstrich (_):
LOG_EVENT, NUMBER_OF_ENTRIES, IS_IMPERIAL
* Makro-Definition sollte nur eigene Parameter verwenden
* Referenzierung lokaler oder globaler Variablen ist problematisch.

23
Q

guter stil

A
  • Bei Funktionen, die mehr als ein Ergebnis zurückliefern
  • Call by reference, oder
  • Strukturtyp definieren
  • Kommentare erhöhen die Lesbarkeit von Code.
  • … wenn Sie sinnvoll eingesetzt werden.
24
Q

Gliederung eines typischen Programms

A

Programme sind üblicherweise etwa wie folgt gegliedert:
1. Erläuternder Kommentar
2. #include – Anweisungen
3. #define – Anweisungen
4. Typdefinitionen
5. globale Variablen
6. Definition eigener Funktionen
7. main – Funktion

25
Q

haufige Syntaxfehler

A

Syntaxfehler
* Fehlendes Semikolon am Ende von Anweisungen
* Fehlende geschweifte Klammer am Ende einer Funktion
* Fehlende Klammern beim Funktionsaufruf
* Falscher Multiplikationsoperator (* verwenden, nicht ·)
* Falscher Zugriff auf Elemente von Strukturen über Zeiger (-> vs. . beachten)
* Adressoperator bei Arrays oder Funktionen verwendet
* Makroparameter nicht geklammert
* Verwechslung von Zuweisung (=) und Gleichheit (==)
* Groß- und Kleinschreibung bei Variablen nicht beachtet

26
Q

Häufige Fehler bei arrays

A
  • Überschreiten von Array-Indizes
  • Gegeben: Array a mit n Element
  • Erstes Element: a[0]
  • Letztes Element: a[n-1]
  • Falsche Verwendung des Adressoperators
  • Array-Bezeichner ohne Index sind Zeiger
  • Beispiel: int a[5]
  • a ist der Zeiger auf das erste Element und entspricht &a[0]
  • &a ist ein Zeiger auf den Zeiger des ersten Elements
27
Q
A