Vorlesung 3 Flashcards
Typen konvertieren
- Wir wissen: In C ist jeder Variable ein Datentyp zugeordnet.
- Variablen lassen sich aber auch in andere Datentypen konvertieren.
- Motivation:
- Es ist ein größerer Wertebereich erforderlich.
- Es ist eine höhere Präzision erforderlich.
- Variablen unterschiedlichen Typs werden miteinander verrechnet.
- Unterschieden wird:
- Implizite Typkonvertierung
- Explizite Typkonvertierung
Implizite Typkonvertierung
- Implizite Typkonvertierung findet automatisch statt, wenn arithmetische
Operatoren auf zwei Operanden von unterschiedlichem Typ angewendet
werden. - Beispiel:
int i;
float f;
i = 15;
f = 1.23f;
i + f;
Das Ergebnis der Addition ist vom Typ float.
● Treffen an einem Operator zwei Variablen/Literalen unterschiedlichen Typs
aufeinander, so hat das Ergebnis den „größeren“ Typ und es wird dessen
Arithmetik verwendet.
* Priorität: long double > double > float > unsigned long
> long (int) > unsigned int > int
* Die kleineren Typen (unsigned) char/short werden in jeden Fall in
(unsigned) int gewandelt
* Genaue Definition siehe z.B.
Dausmann, Bröckl, Goll, C als erste Programmiersprache, 6. Auflage, Kapitel 7.7
Bei Zuweisung einer Variablen an eine Variable mit „kleinerem“ Typ wird
versucht, den Typ so gut wie möglich zu erhalten.
char i;
double f;
f = 1.23;
i = f; «<i wird zu 1
f = 2.3e12;
i = f; «< nicht definiert
weiteres beispiel:
int i, j, k;
double f, g, h;
char c;
i = 2;
j = 3;
h = 3.0;
f = i / j;
g = i / h;
printf(“f = %g\n”, f);
printf(“g = %g\n”, g);
k = 65;
c = k;
printf(“%c\n”, c);
Explizite Typkonvertierung
● Gelegentlich kommt es vor, dass der Typ einer Variablen nicht den
Anforderungen genügt, z.B.
* mit einem int soll plötzlich wie mit einer Gleitkommazahl gerechnet werden
* ein int soll als Zeichen interpretiert werden
● Explizite Typkonvertierung:
(typ)var interpretiert var als wäre sie vom Typ typ
int a = 5, b = 2;
printf(“Gleitkommadivision: %g\n”, (double)a / (double)b);
Funktionen
- Häufig beinhalten Programme Teile, die wiederverwendet oder mehrfach
ausgeführt werden müssen. - Beispiel: Standardfunktionen für Ein- und Ausgabe
- Dieser Code wird in einer Funktion definiert, die an den entsprechenden
Stellen aufgerufen wird. - Vorteile:
+ kürzere Programme
+ einfache Wartung (Korrektur, Erweiterung)
Benutzen von Funktionen
● Aufruf über den Namen (Bezeichner) der Funktion
● Funktionen können Parameter besitzen. Diese müssen beim Aufruf in
Klammern angegeben werden:
● Funktionen können einen Rückgabewert besitzen:
double x, y = 3;
x = sin(2);
cos(y);
stdio.h
● In der Datei stdio.h sind Ein-und Ausgabefunktionen definiert.
● Einbinden mit #include <stdio.h>
● Operationen für Bildschirm-Ein- und Ausgabe wie auch für Dateioperationen
● Gehört zu den mitgelieferten Standardbibliotheken</stdio.h>
putchar() und getchar()
● putchar: Schreibt ein Zeichen auf Bildschirm
● getchar: Liest ein Zeichen von Tastatur
#include <stdio.h>
int main()
{
char z;
/* Zeichen einlesen */
z = getchar();
/* Zeichen wieder auf Bildschirm schreiben */
putchar(z);
return 0;
}</stdio.h>
Ausgabe mit printf()
● Formatierte Ausgabe von Variablen und Literalen (Grundtypen)
● Rückgabewert: Anzahl der tatsächlich ausgegebenen Zeichen
● Syntax: int printf (formatstring [,parameter])
● Beispiel:
#include <stdio.h>
...
int alter;
alter = 15;
printf("Hans ist %d Jahre alt.\n", alter);</stdio.h>
Der Formatstring von printf()
include <stdio.h></stdio.h>
● Der Formatstring besteht aus Ausgabetext und/oder Formatanweisungen.
● Text wird unverändert ausgegeben.
● Formatanweisungen bestehen aus Prozentzeichen % und Zeichen, die den
Datentyp angeben.
● Die Formatanweisung
wird durch den nächsten,
noch nicht bearbeiteten
Parameter von printf
ersetzt.
…
int a, b, c;
a = 5;
b = 7;
c = a + b;
printf(“%d + %d = %d\n”, a, b, c);
Die wichtigsten Formatanweisungen
%d, %i int (auch short int und char); dezimal mit Vorzeichen
%u int; dezimal ohne Vorzeichen
%o int; oktal ohne Vorzeichen
%x, %X int; hexadezimal mit kleinen bzw. Großen Buchstaben
%c char; Zeichen (ein Buchstabe / eine Ziffer, …)
%s char*; Zeichenkette bis Zeichen ‚\0’ gelesen wird
%f, %e, %g Fließkommaschreibweise (e/E = Exponatenschreibweise klein/groß)
float/double
%lf, %le, %lg Fließkommaschreibweise (e/E = Exponatenschreibweise klein/groß)
float/double
%Lf, %Le, %Lg Fließkommaschreibweise (e/E = Exponatenschreibweise klein/groß)
long double
Alle Formatanweisungen und weitere Erläuterungen finden sich in
den man-Pages zu printf
Erweiterte Formatanweisungen
● ermöglicht z.B. numerische Werte spaltenweise auszugeben oder die Anzahl
der Dezimalstellen zu begrenzen
● Syntax:
* %[flags][width][.preci][l]type
● flags:
* -: linksbündige Ausgabe
* +: Vorzeichenausgabe auch bei positiven Zahlen
* #: Alternative Darstellung (s. man-page)
* 0: Auffüllen mit Nullen für Breite
* Leerzeichen: Leerzeichen vor positiver Zahl
● Syntax:
* %[flags][width][.preci][l]type
● width: minimale Breite des Ausgabefeldes
* wenn Ausgabe größer: Breitenangabe wird ignoriert
* wenn Ausgabe kleiner: linksbündig werden Leerzeichen eingefügt
● .preci: Anzahl der auszugebenden Dezimalstellen bei Fließkommazahlen
● l: long-Version des Datentyps
● type ist eine einfache Formatanweisung
Eingabe mit scanf()
● Dient zur formatierten Eingabe von Variablen
● Rückgabewert: Anzahl der tatsächlich eingelesenen Eingaben (evtl.
Fehlerkorrektur)
● Syntax: int scanf (formatstring [,parameter])
Der Formatstring von scanf()
● Der Formatstring besteht Formatanweisungen, Whitespaces und anderen
Zeichen
* Formatanweisungen bestehen aus Prozentzeichen % und Zeichen, das den
Datentyp der Eingabe angibt
* Whitespaces passen zu einem Leerraum jeder Größe
* Andere Zeichen passen nur zu sich selbst
● Eingaben werden an die als Parameter übergebenden Adressen
geschrieben, d.h. vor den Variablennamen muss das Zeichen & geschrieben
werden
Von-Neumann-Rechnerkonzept
- Beschrieben von John von Neumann 1945/46
- Fast alle modernen, gebräuchlichen Computer basieren im Wesentlichen auf
diesem Konzept - Allgemeine Struktur, unabhängig vom Problem
- Hauptkomponenten: Rechenwerk, Steuerwerk, Arbeitsspeicher,
Ein-/Ausgabeeinheit, Verbindungsbus - Programme und Daten liegen im selben Speicher.
- Speicher ist in gleichgroße Zellen aufgeteilt, Zugriff über
fortlaufende Adressen - Befehle und Daten werden binär gespeichert.
- Programme werden taktgesteuert sequentiell abgearbeitet
(Ausnahme: Sprungbefehle, bedingte Verzweigungen). - Arithmetische, logische und Transportbefehle, bedingte Sprünge,
Ein- und Ausgabe-Befehle, Unterbrechung
Von-Neumann-Prinzip: Komponenten
● Rechenwerk (Arithmetic Logic Unit,
ALU): führt Rechenoperationen und
logische Verknüpfungen aus
● Steuerwerk (Leitwerk, Control Unit):
steuert die Befehlsabfolge, interpretiert
die Anweisungen eines Programms
● Speicherwerk: Speichert Programme
und Daten
● Ein-/Ausgabewerk: steuert Ein- und
Ausgabe (z.B. Tastatur, Monitor)
Der Verbindungsbus
- Das Bus-System teilt sich in drei Bestandteile
- Datenbus: überträgt die Daten zwischen den einzelnen Komponenten des
Rechners. Je mehr Leitungen zur Verfügung stehen, desto schneller können
Daten übertragen werden
(typische Busbreiten: 4, 8, 16, 32, 64 Bit). - Adressbus: überträgt die Speicheradressen. Je mehr Leitungen zur Verfügung
stehen, desto größer ist der nutzbare Speicher. - Steuerbus: steuert die Kommunikation im Bussystem: Bustakt,
Schreib-/Leserichtung, Reset, Statusleitungen …
Ein einfaches Rechenwerk
- Dieses Rechenwerk verknüpft maximal
zwei Operanden - Operand wird zuvor im Akkumulator
(Akku) gespeichert, einem
Allzweckregister, in das auch das
Ergebnis geschrieben wird für evtl.
weitere Rechenschritte (ein Register ist
eine Speicherstelle direkt an der CPU)
- Operand wird zuvor im Akkumulator
- Operand direkt aus dem Speicher
- Auszuführende Operation vom
Steuerwerk - Ergebnis wird im Akku und
Arbeitsspeicher abgelegt - Flags werden an das Steuerwerk
zurückgeliefert, beeinflussen u.U. den
weiteren Programmablauf
Von-Neumann-Zyklus: Programmablauf
- Fetch: Der nächste Befehl wird aus dem Speicher in das
Befehlsregister der CPU geladen - Decode: Befehl wird für das Rechenwerk übersetzt
- Fetch Operands: Die Operanden für den Befehl werden aus dem
Speicher in die Register des Rechenwerks geladen - Execute: Rechenwerk führt den Befehl mit den Operanden aus
- Update Instruction Pointer: Erhöhe den Befehlszähler um 1
(wenn zuvor kein Sprungbefehl)
Der Arbeitsspeicher
- Wahlfreier Zugriff (RAM: Random Access Memory)
- Schreib- und Lese-Zugriff möglich
- Speicherzellen sind fortlaufend nummeriert (Adressen)
- Jede Speicherzelle ist einzeln adressierbar
- Eine Speicherzelle speichert 1 Byte
- 1 Byte besteht aus 8 Bit
- 1 Bit kann den Wert 0 oder 1 annehmen (binary digit)
- 1 Byte kann Werte von 0 bis 255 speichern
- Die „Breite“ des Datenbusses bestimmt, welche Datenmenge in einem Zyklus
gelesen werden kann (z.B. 64 Bit = 8 Byte). - Die „Breite“ des Adressbusses bestimmt die maximal adressierbare Menge von
Speicherzellen.
Von-Neumann-Flaschenhals
- In früheren Zeiten waren Speicher und Busse deutlich
schneller als die CPU. - Durch optimierte und parallele Berechnungen innerhalb der
CPU ist diese nun erheblich schneller als Busse und Speicher. - Befehle und Daten müssen über den selben Bus aus dem selben Speicher
geholt werden, dies führt zu einem Engpass (Flaschenhals) und damit
Verzögerungen. - Abhilfe: Cache-Zwischenspeicher
- extrem schneller Speicher direkt an oder nahe der CPU
- hält Kopien von Teilen des Arbeitsspeichers
- „intelligente“ Vorhersagemechanismen, welche Speicherzellen dort sinnvoll
zwischengespeichert werden
Harvard-Architektur
- Jeweils eigener Speicher und Bus für
Befehle und Daten - höhere Geschwindigkeit, Befehle und Daten
können parallel geladen werden - unbeabsichtigtes Überschreiben von
Programmcode ausgeschlossen - Busse können unterschiedliche Breite
haben - Nachteil: unflexible Speicherausnutzung
- Einige Spezialprozessoren arbeiten nach
dem Harvard-Prinzip - Viele aktuelle Prozessoren haben intern in
Teilen eine Harvard-Architektur, z.B. Datenund Befehlscache bzw. -pipelines
Zeichen, Daten, Information, Wissen
- Zeichen
- kleinste Datenelemente, z. B. Buchstaben, Ziffern, Sonder- und Steuerzeichen
- Stehen für sich alleine und sind zusammenhangslos
- (strukturierte) Daten
- Kombination von Zeichen basierend auf einer Syntax
- Keine inhaltlichen Bedeutung / Verwendungshinweis
- Informationen
- Daten im Kontext eines Problemzusammenhangs
- Für den Anwender verständliche, inhaltliche Bedeutung
- Wissen
- Ergebnis der individuellen Verarbeitung von Daten und Informationen
- Handlungsorientiert / führt zur Lösung von Aufgabenstellungen
Zeichenrepräsentation im Computer
- Zeichen werden im Computer als Bit-Folgen (binär) repräsentiert
- Kodierungen erlauben die Übersetzung zwischen menschlich verständlichen
Zeichen (z.B. „A“) und Binärcode (z.B. „0100 0001“)
ASCII-Code
- ASCII = American Standard for Coded Information Interchange
- Abbildungsvorschrift zur binären Kodierung von Zeichen
- 1963 als Standard veröffentlicht und 1968 zuletzt aktualisiert
- 7-Bit-Zeichenkodierung
- Bitmuster (interpretiert als Zahlen von 0 bis 127)
- 95 darstellbare Zeichen, 33 Steuer- & Sonderzeichen (nicht darstellbar)
- Enthält ausschließliche Zeichen des englischen Alphabets, daher keine Umlaute (ä, ö, ü)
oder Akzentzeichen (á, Ñ, æ, …) - Problem: Internationale Sprachvielfalt wird nicht abgedeckt!
- Repräsentation in einem Byte (8 Bit): 8. Bit für
- Fehlerkorrektur auf Kommunikationsleitungen,
- Steueraufgaben
- Erweiterung auf 8-Bit-Code → 128 weitere Zeichen kodierbar
Zeichensatz ISO 8859-x
- 15 verschiedene 8-Bit-Zeichensätze für die Informationstechnik
- Die ersten 128 Zeichen entsprechen dem ASCII-Zeichensatz.
- Es folgen 32 (wenig benutzte) Steuerzeichen.
- Die letzten 96 Positionen enthalten regionale Sonderzeichen und machen
den Unterschied zwischen den Teilnormen aus. - Beispiele:
- ISO 8859-1 Latin 1 (Westeuropäisch) gilt für Deutschland
- ISO 8859-6 (Arabisch)
- ISO 8859-7 (Griechisch)
- ISO 8859-1 ist neben US-ASCII und UTF-8 die wohl am häufigsten
gebrauchte Kodierung für lateinische Schriften.
Microsoft-Welt: Codepage 850 und 1252
- Betriebssystem MS-DOS
- Kodierung mit Codepage 850
- Relevant bei Ausführung von Java-Programmen über die DOS-Konsole /
Eingabeaufforderung - Betriebssystem Windows
- Kodierung mit Codepage 1252
- Zentral- und Osteuropäische Sprachen
- Entspricht nur in weiten Teilen ISO 8859-1, es gibt Inkompatibilitäten
Unicode / UCS
- UCS = Universal Coded Character Set (ISO-Norm 10646)
- Alphanummerischer Zeichensatz der ISO zur Kodierung von Buchstaben,
Satzzeichen, Sonderzeichen, Ziffern - Ziel: Zeichen / Textelemente aller bekannten Schriftkulturen und
Zeichensysteme festhalten - Ständige Erweiterung
- Version 1.0 1991: 7.161 Zeichen
- Version 2.0 1996: 38.950 Zeichen
- Version 14.0 2021: 144.697 Zeichen
- Kodierung mittels UCS Transformation Format (UTF)
Unicode Transformation Format utf8 und utf32
- UTF-16
- Jedes Zeichen besteht aus ein oder zwei 16-Bit Einheiten
- Interne Zeichenkodierung
- in den Betriebssystemen Windows, OS X
- Java
- UTF-32:
- 4 Byte (32 Bit) pro Zeichen
- Damit 232 = 4.294.967.296 Zeichen
- Vorteil: Fixe Breite für jedes Zeichen
- Nachteil: Für jedes Zeichen 4 Byte Speicherbedarf
Unicode Transformation Format (UTF)
- Jedem Zeichen ist ein Code-Punkt (Index) zugeordnet. UTF beschreibt, wie
dieser Code-Punkt als Unicode-Zeichen dargestellt wird. - UTF-8:
- Zeichen werden aus 1-4 Byte kodiert:
- Erste 128 Zeichen deckungsgleich mit ASCII (1 Byte)
- Bei 1 Byte: 0xxxxxxx
- Bei 2 Byte: 110xxxxx 10xxxxxx
- Bei 3 Byte: 1110xxxx 10xxxxxx 10xxxxxx
- Bei 4 Byte: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
- De-facto-Standard-Zeichenkodierung des Internets
- Interne Zeichenkodierung in den Betriebssystemen GNU/Linux, Unix
Beispiel für nicht-alphanumerische Daten
- Bilder werden in einzelne Punkte zerlegt.
- Jeder Bildpunkt (Pixel) hat eine Farbe, die sich z.B.
aus den Grundfarben Rot, Grün und Blau
zusammensetzt. - Die Anteile der Grundfarben werden als Zahlen
angegeben, so dass man pro Bildpunkt drei Zahlen
codiert. - Töne sind Schwingungen/Wellen. In festen
Zeitintervallen wird ein Wert abgetastet und als
Zahl codiert. - Fazit: alle Informationen werden in Zahlen
umgewandelt, die binär gespeichert und
verarbeitet werden.