http://www.sirius-net.de
Inhaltsverzeichnis Programmiersprachen *
a) Compiler *
b) Interpreter *
c) "Zwischendinger" *
Geschichtliche Entwicklung *
EDV *
PAP *
Programm *
Programme im Hauptspeicher *
Zahlensysteme, Bits & Bytes *
Zahlensystem zur Basis b: Ziffern 0 ..... b-1 *
Zeichensätze *
Aufbau der ASCII-Tabelle: *
Bezeichner (gültig für C/C++) *
Konstanten im Quelltext *
Wichtige Steuerzeichen *
Grunddatentypen und Variablen *
Grunddatentypen sind in C numerische Typen *
Datentypen *
Grunddatentypen und Variablen *
Einige Deklarationen: *
Aufbau einfacher C-Programme *
Übersicht: *
printf () *
Strings (Zeichenketten) *
gets( ) und puts( ) *
Konvertierung von Strings geeigneten Inhalts in nummerische Typen *
A) Prinzip *
B) Die Funktionen *
Operatoren und Ausdrücke *
Kombinierte Zuweisungsoperatoren *
Eigenschaften von Operatoren *
2. Priorität (Reihenfolge) *
3. Assoziativität oder Bindungsrichtung *
4. Datentypen, die verarbeitet werden und gegebenenfalls Typ des Ergebnisses *
Addition/Subtraktion/Multiplikation *
Division *
Modulo-Operator *
Winkelfunktionen *
Bedingungen (Bool´sche Ausdrücke) *
Operatoren zur Formulierung von Bedingungen *
if- und if/else Konstruktionen *
Entscheidungen: Die switch/case Kaskade *
Konditionaloperator *
Entscheidungskonstruktionen on C/C++ geordnet nach allgemeiner Verwendbarkeit: *
Schleifen (Wiederholung von Anweisungen) *
Typen von Schleifen: *
2. for Schleife *
do ... while Schleife *
Ergänzende Befehle zur Programmablaufsteuerung *
Einsatz: Werkzeug zur Erzeugung neuer Programme
Prinzip: Textdatei (Quelltext) Regeln der Programmiersprache beachten
Programmiersprache * Programm
Implementiert als
Programm übersetzt (Quell-)Text in Maschinensprache. D.h. es entsteht eine lauffähige Datei (*.exe) Kann auf dem entsprechenden Betriebssystem direkt von der CPU ausgeführt werden.
Typische Beispiele: C/C++; PASCAL, FORTRAN;
C++ ist eine Erweiterung von C; Erweiterung um Objektorientierung
Assembler: Aus einem Befehl wird ein Maschinenbefehl. (1:1 Compiler) Maschinenabhängig!
Bei höheren Sprachen wird aus einem Befehl mehrere Maschinenbefehle (1:N Übersetzung) Quelltexte können portabel sein
Es wird eine Laufzeitumgebung benötigt, der Interpreter, der den Quelltext zeilenweise liest und jede Zeile und jede Zeile vor ihrer Ausführung übersetzt. Die Ausführung ist also sehr viel zeitaufwendiger.
Typische Vertreter sind viele Basic-Implementierungen; Perl; Shell-Scripte (« Batch-Dateien)
Der "Compiler" erzeugt sogenannten Byte-Code, der komprimierter als der Quelltext ist, aber kein Maschinencode, sondern unabhängig von der CPU.
Um die Programme laufen zu lassen wird trotzdem eine Software gebraucht, die in der Lage ist das Ding abzuarbeiten (Java-Interpreter, meist schon im Web-Browser integriert), aber der Code ist komprimierter. Also eine Kompromis-Lösung zwischen a) und b) Programme sind schneller als Quelltext mit Interpreter, aber langsamer (um ca. Faktor 10) als compilierte Programme. Rechenintensive Programme sind hierfür also nicht geeignet.
Java ist von der Syntax her mit C/C++ eng verwandt.
Maschine mit CPU Problem
Algorithmus: Verarbeitungsvorschrift, die so genau formuliert ist, daß sie von einer Maschine abgearbeitet werden kann.
Algoritmus läßt sich darstellen aus
Anweisungsfolge
Anweisungsfolge
Nimmt in C/C++ Textersatz am Quelltext vor. Insbesondere
kann mit #include der Inhalt anderer Textdateien in den Quelltext aufgenommen
werden.
Das Programm wird aufgerufen. Der Loader des Betriebsystems
lädt ein Abbild (Kopie) der *.exe Datei in den Hauptspeicher, und
setzt diese Programmausführung am Entry Point (s.o.) des Programms
auf. Die im Hauptspeicher liegende "Kopie" des Programms heißt Prozeß
(UNIX) oder Task (Windows)
Daten-Abschnitt
(Datensegment) Variablen |
Code-Segment
(Verarbeitung, Algorithmus) |
Stack |
3 | 4 | 5 | 0 |
3 | 2 | 1 | 0 |
Zahl zur Basis 10:
3 * 103 + 4 * 102 + 5 * 102 + 0 * 100
3 + 1000 + 4 + 100 + 5 * 10 + 0 * 1
Zahlensystem zur Basis b: Ziffern 0 ..... b-1
10 Dezimal 0 ...... 9
2 Binär 0, 1
23 8 Oktal 0 ...... 7
24 16 hexadezimal 0 ....... F
Binär: In diesem Zahlensystem arbeitet der Rechner intern, d.h. die Daten liegen im 2er System als Bitmuster vor (Folge von Nullen und Einsen)
Dezimal: Wird zur Kommunikation mit dem Anwender
benutzt.
Kleinste Informationseinheit
1 Bit,
Zahl der darstellbaren Werte: 2 ( 0 bzw. 1 )
Faßt man mehrere Bits zu einer größeren
Informationseinheit zusammen, so können mehr unterschiedliche Informationen
dargestellt werden.
Üblich : 8 Bit 1 Byte
1 Byte:
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
Jedes Bit im Byte kann den Wert 0 oder den Wert 1 annehmen. Das heißt ein Byte kann 28 verschiedene Zustände annehmen = 256 (dezimal)
In C entspricht dem Byte der Datentyp unsigned char (s.u.)
0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 85 | ||||||
1 | 2 | 5 | 125 okt | |||||||||||
0 | 0 | 0 | Kleinste Einheit 0 |
1 | 1 | 1 | Größte Einheit 7 |
0 | 0 | 0 | 0 | 0 dezimal |
1 | 1 | 1 | 1 | 15 dezimal F (hex) |
0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | Binär |
|
|
Hex |
Egal wie die Eingabe erfolgt, als 65 (dezimal), 41 (hex) oder 101 (oktal) führt intern immer zum gleichen Bitmuster:
0 ... 31 (dezimal): Steuerzeichen
Bsp.: 08 (dez) Backspace
09 (dez) TAB
13 (dez) RETURN
12 (dez) Form Feed (Drucker: Neue Seite)
48 ... 57 (dezimal): Ziffern 0 ... 9
30 ... 39 (hexadezimal)
65 ... 122 (dezimal) Buchstaben (engl. Alphabet)
A ... Z a ... z
A | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 65 dez |
a | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 97 dez |
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Bit-Position |
Kleine und große Buchstaben unterscheiden sich nur an der 5. Bit-Position. Bei großen Buchstaben ist das 5. Bit gelöscht, bei kleinen Buchstaben ist es gesetzt. Rein rechnerisch beträgt der Unterschied immer 25 = 25 dez = 20 hex. Gilt nur für die Buchstaben des englischen Alphabets, also ohne Sonderzeichen und Umlaute.
Die Aussage »A« ist kleiner als »a« ergibt sich aus den zugeordneten Werten aus der ASCII-Tabelle ( 65 dez = A < 97 dez. = a )
Verläßlich bei der ASCII-Tabelle sind nur die Dezimal-Werte von 0 bis 127
Zeichen ohne Bild
32 (dezimal) blank (Leertaste)
20 (hex)
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Anders die Ziffer »0«, die den Wert 48 (hex) bzw. 30 (hex) hat
0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | Binärzahl |
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Bitfolge |
32 d | 16 d | 1 | 0 | Wert |
Ganze Zahlen mit und ohne Vorzeichen
a | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
b | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Frage: Ist a größer als b ? Nein, wenn MSB kein Vorzeichen ist sondern eine gültige Stelle, dann 0 < 255
Das Bit, das am weitesten links steht (mit der höchsten
Nummer) nennt sich
MSB (most significant bit).
Dieses Bit kann als Vorzeichen interpretiert
werden. Für diesen Fall ist die
Zahl negativ, wenn MSB = 1
"Zweierkomplement-Arithmetik":
Ausgangszustand: 11111111
kippen 00000000
+1 00000001
a | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
b | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
A ist in dem Fall größer wie b, denn MSB ist Vorzeichen und somit 0 > -1
In C/C++ wird das unterschieden durch die Datentypen
Unsigned char = MSB ist kein Vorzeichen Wertebereich: 0 ... 255
Signed char = MSB ist Vorzeichen Wertebereich: -128 ... +127
K & R | C, wie es erfunden wurde, beschrieben in Kernighen/Ritchie ""The C Programming Language", 1. Auflage (dt. Übersetzung: "Programmieren in C") | Ab 1970/71 |
ANSI-C | ANSIKommitte verabschiedet
Standard zu C
(ANSI ist das amerikan. Gegenstück zu DIN) |
1989 |
ANSI C++ | Ab 1989 entwickelte Bjarne
Stronstrup C zu C++ weiter
"Die C++ Programmiersprache" bei Edison-Wesley |
1998 |
Einzelne Zeichen |
|
|
|
Eingeschlossen in einfache Hochkommata | |||
Ganze Zahlen, Basis 10 |
|
|
|
Keine besondere Kennzeichnung | |||
Ganze Zahlen, Basis 16 |
|
|
|
Führendes 0x als Kennzeichnung für hexadezimal | |||
Ganze Zahlen, Basis 8 |
|
|
|
Beginnt mit führender Null | |||
Floating point-Konstanten,
immer zur Basis 10
Trennzeichen ist Punkt |
|
|
|||||
|
|
||||||
|
|
||||||
|
|
||||||
Zeichenketten
« strings |
|
Eingeschlossen in doppelte Hochkommata | |||||
|
Steuerzeichen, Ersatzdarstellung
für "new line".
Steuerzeichen werden mit \ (Backslash) einleitet |
||||||
Ausgabe von " geht, indem in einem String durch |
|
||||||
Ausgabe von \ in einem String durch |
|
||||||
\n | New line |
\t | Tabulator |
\b | Back Space |
Datentyp | Variable |
Mit Vorzeichen (signed) Ohne Vorzeichen (unsigned) |
plus |
Beispiel einer Variablen-Deklaration:
Datentyp | Name | ; | ||
ganzzahliger Typ mit Vorzeichen | int | i | ; | Deklariert eine Variable i von Typ int |
i = 375 | ; | weist der Variablen i die Konstante / den Wert 375 zu | ||
Ganzzahltypen | floating point Typen | ||
Mit Vorzeichen | Ohne Vorzeichen | Mit Nachkommastellen | |
signed | Unsigned | Immer mit Vorzeichen | |
signed char | unsigned char | float | |
Int | double | ||
long double |
Signed char | Unsigned Char | |||
Int « signed int | Unsigned int | Float | ||
Long int | Unsigned long int | Double | ||
Long double | ||||
unsigned char 8 Bits0 bis 255
char 8 Bits -128 bis 127
enum 16 Bits -32768 bis 32767
unsigned int 16 Bits 0 bis 65535
short int 16 Bits -32,768 bis 32767
int 16 Bits -32,768 bis 32767
unsigned long 32 Bits 0 bis 4294967295
long 32 Bits -2147483648 bis 2147483647
float 32 Bits 3.4 * 10-38 bis 3.4 * 10+38
double 64 Bits 1.7 * 10-308 bis 1.7 * 10+308
long double 80 Bits 3.4 * 10-4932
bis 1.1 * 10+4932
int i, ,j, k ;
long x;
double hoehe, breite, y ;
int l ; float f ;
#include <stdio.h> | Das Programm soll die Text-Datei stdio.h hier in den Quelltext aufnehmen |
Void main ( ) | Das Hauptprogramm |
{ | Programmblock, der zu main ( ) gehört. Was hier zwischen bis zur geschlossenen geschweiften Klammer steht, ist alles Inhalt der Funktion main () |
|
Variablen-Deklaration
Muß vollständig vor dem Anweisungsteil stehen! |
Anweisungsteil / Alogorithmus | |
} |
stdin | stdout |
Standardeingabe | Standardausgabe |
Tastatur | Bildschirm |
Alles, was mit Ein- /Ausgabe zu tun hat wird in C prinzipiell über (Standard-)Funktion erledigt. Kommt also aus einer Bibliothek.
Art der gelesenen / geschriebenen Daten | lesende Funktion | schreibende Funktion |
Alle Grunddatentypen und strings | scanf () | printf () |
ptrings | gets () | puts () |
Ein Zeichen | getchar () | putchar () |
Standard: ANSI
#include <stdio.h> |
printf () | "print formatted to stdout" | |
printf ("\033[2J") ; | String in doppelten Hochkommas | |
\033
\0x1B 27 |
ESC | Kann in einem string jedes beliebige ASCII-Zeichen darstellen |
[2J
|
Löscht den Bildschirm | Anweisung wird von geladenem ANSI-Treiber ausgeführt |
i = A | ||
printf("%c %d(dez) %X (hex) %o (okt) \n " i,i,i,i) ; | Das 1. Argument von printf
() ist immer eine Zeichenkette.
Diese kann enthalten:
|
|
printf("Inhalt der Variable l : %ld\n",!) ; | %ld | Ausgabe Datentyp long im Format dezimal |
d = 4.0 * atan (1.0) ; | atan | Arcus Tangenz
das Ergebnis der Rechnung rechts vom Gleichheitszeichen ist nachher der Wert von d |
printf("Inhalt der Variable d : %lf \n", d) ; | Berechnet Ë auf Rechnergenauigkeit | |
printf("So geht es auch: %lf\n", 4.0*atan(1.0)) ; | Berechnet den Wert direkt. Ohne Umweg über eine Variable | |
y=sqrt(x); | Berechnet Quadratwurzel von
x und stellt es in die Variable Y
Fast alle mathematischen Funktionen haben den Datentyp double Die Variablen x und y sollten daher im Vorfeld ebenfalls als Datentyp double deklariert worden sein. |
|
%7.3lf | % | Leitet Formatbeschreiber ein |
if | Zu double passender Formatbeschreiber | |
7.3 | 7 = Gesamtbreite der Ausgabe
(Vorschlagscharakter; wenn mehr Platz benötigt, holt ihn sich das
Programm), davon sind
3 = Anzahl der Nachkommastellen (verbindlich) Die Kommastelle zählt mit ! Für die Bildschirmausgabe wird die letzte Nachkommastelle von printf () kaufmännisch gerundet. Intern bleibt der Gesamtwert erhalten. |
|
printf ("%s\n" , "Weiterhin viel Spaß mit C ! \n") ; | ||
} | ||
Um die folgenden Zeichen am Bildschirm auszugeben ist an Syntax nötig: | % | %% |
\ | \\ | |
" | \" |
scanf() |
read formatted from stdin |
int i ; | |
printf("ganze Zahl eingeben - > ") ; | |
scanf("%d", &i) ; | /* & = Adressoperator; Wirkung: ermittle Adresse der Variablen i */ |
/* scanf() liest auf Adressen ein ! */ | |
/* Die Adresse einer einfachen
Variablen wird in C mit dem Adressoperator & ermittelt.
Ausnahme: Arrays (s.u.) |
|
&i
|
/* Adresse von i */ |
I
|
/* "Nicht-Adresse" Wert bzw. Inhalt von Speicherplatz i */ |
%d
|
/* Auch das erste Argument von scanf() ist eine Zeichenkette. In dem Fall steht der Formatbeschrieber pasend zum einzulesenden Datentyp: ganzzahlig dezimal. */ |
%d
|
/* Achtung: hier nur den Formatbeschreiber eintragen !. Falls in dieser Zeichenkette Text und/oder ein Steuerzeichen steht, würde scanf() genau auf deren Eingabe warten. */ |
/* Ab dem ersten Zeichen, das nicht zum Formatbeschreiber passt, läßt scanf() den Rest der Eingabe im Eingabepuffer stehen. Daher sollte scanf() wenn mit der Tastatur gearbeitet wird mit dem Befehl fflush(stdin); kombiniert werden. */ | |
fflush(stdin) ; | /* Bereinigt den Eingabepuffer */ |
scanf("%s" , .. ) ; | liest den string nur bis zum ersten blank, TAB oder CR |
String ist eine Folge von ASCII-Codes, die hintereinander
im Speicher stehen.
1 ASCII-Code passt in eine char-Variable. Gelingt
es mehrere solche char-Variablen sauber hintereinander im Speicher anzulegen,
ensteht eine "Variable für einen String".
Konstruktionen, die aus mehreren Variablen gleichen
Typs bestehen, heißen Array und werden von C unterstützt.
"Hallo" | String-Konstante | |
Beispiel einer Array-Deklaration: | ||
char f[81] ; | Array, bestehend aus 81 Elementen
vom Typ char
80 Zeichen plus Abschluß 0 |
|
[ ] | Ankündigung Array | |
81 | Größe des Arrays | |
f | Name des Array | |
'H' | 'a' | 'l' | 'l' | 'o' | . . . |
Namen von Arrays verhalten sich anders als Namen von einfachen Variablen. Array ist selbst eine Adresse
Arraynamen sind in C Adressen.
Arrayname « der Adresse des ersten Arrayelements
Wenn ich mit scanf( ) und %s einen string einlesen will, hat das die Besonderheit, daß er nur bis zum ersten Blank, TAB oder CR einliest. Der Rest fällt unter den Tisch.
Das String-Format von C ASCII-Z Format
Ausgelesen wird bis zur Abschluß-Null 00 (hex)
Achtung: Der vordefinierte Adressraum für das
Array solte nicht zu klein ausgelegt sein.
scanf( ) überprüft nur die Einsprungsadresse
und schreibt die Eingaben bis zur Abschluß-Null. Wenn der Anwender
über den vordefinierten Bereich hinausschreibt, wird der Inhalt nachfolgender
Speicheradressen überschrieben / zerstört.
char f[81] | ||||||||||||||||||||
f 3050 | 'H' | 'a' | 'l' | 'l' | 'o' | 0 (dez) | ||||||||||||||
Adresse
|
3050 | Adresse ist nur fiktiv | ||||||||||||||||||
ASCII | 'B' | 'o' | 'n' | 'd' | '-' | '0' | '0' | '7' | 0 | |||||||||||
Hex | 42 | 6F | 6E | 64 | 2D | 30 | 30 | 37 | 00 |
String von stdin einlesen, bzw. nach stdout schreiben.
char f[81] ; | ||
printf("Bitte Zahlenkette eingeben: ") ; | ||
gets(f) ; | /* Arrayname ist die Adresse, ab der gets( ) den string im Hauptspeicher ablegen kann. */ | Auch hier gilt: Lieber etwas größer wegen dem Überlauf der Eingabe. Siehe oben. |
/* übernimmt Zeichen von stdin, bis [Return] kommt. Diese Zeichen werden an der Adressen (hier: f) hintereinander im Hauptspeicher abgelegt. */ | ||
/* An Stelle von [Return] (13 d) wird die Strin-Ende-Null (0 d) im Array abgelegt. */ | ||
puts(f) ; | /* Gibt an dem ihm übergebenen Adresse (hier: f) sol lange Zeichen nach stout aus, bis die Strng-Ende-Null gefunden wird.Statt der String-Ende-Null wird ein »\n« (new line) ausgegeben | |
printf("%s\n" , f) ; | ||
|
|
|
|
|||||||||
|
|
|
Anwendereingabe: A B C [return] Tastatureingabe
intern. Format: 31 32 33 00 hex
0x30 1 2 3 hex
*102 *101 *100
Zwischenergebnis 100 + 20 + 3
Ergebnis: 123 (dez) binär kodiert in einer nummerischen variablen z.B. vom Typ int.
ascii to
Rückgabetyp | Name der Funktion | |
int |
atoi ( ) ascii to integer | Adresse, ab der der String steht, meist ein Arrayname. |
long |
atol ( ) ascii to long | |
double |
atof ( ) ascii to double |
Beispiel:
char f[81]; int i ;
printf("Zahl eingeben -> ") ;
gets(f) ;
i = atoi(f) ;
führende Blanks und Tabs werden überlesen
Vorzeichen -sofern vorhanden- werden berücksichtigt. Kein Vorzeichen wird als positiver Wert interpretiert.
Ab jetzt werden nur noch konvertierbare Zeichen verarbeitet.
Dies sind:
Ziffern (alle 3 Funktionen atoi ( ); atol ( ); atof
( ))
Bei atof ( ) zusätzlich noch: Dezimalpunkt;
E und e für die Exponentialschreibweise; ein zweites Vorzeichen für
den Exponenten. (z.B. 27.89; 1.8E4; -2.6E-3; 2.9e7)
Die Verarbeitung endet, wenn
a) die String-Ende-Null erreicht ist oder
b) das erste nicht konvertierbare Zeichen auftritt.
Ist bereits das erste Zeichen nicht konvertierbar,
geben die Funktionen Null (0 bzw. 0.0) zurück.
Zeichenweise Ein-/Ausgabe
putchar( )
%c %X %d %o
|
|||
getchar( ) | int i;
printf("1Zeichen eingeben ->") ; i = getchar( ) ; fflush(stdin) ; |
/* Hinweis: getchar( ) liest 1 Zeichen ein, wartet auf [Return]. Da dies nicht eingelesen wird von getchar( ) bleibt es im Tastaturpuffer. Damit es dort wieder rauskommt, muß mit fflush(stdin) der Puffer wieder geleert werden. */ | |
An Ein- / Ausgabefunktionen gibt es 6 Stück
Achtung: kein Standard ! #include <conio.h> console i/o |
||
getch( ) ; | int i ;
i = getch( ) ; |
getch( ) zeigt nichts am
Bildschirm an. Das eingelesene Zeichen wird nur Programmintern in die Variable
gestellt.
So kann ein Programmablauf angehalten werden bis ein Tatstendruck erfolgt. |
getche( ) ; | int i ;
i = getche( ) ; |
getche( ) zeigt eingelesenes Zeichen am Bildschirm |
Beide lesen 1 Zeichen ein,
warten nicht auf [Return].
Kein fflush(stdin) nötig ! |
Rückgabewerte von Funktionen muß man in C nicht zuweisen. Nur bei Bedarf !
Hinweis: Ursache der Meldung "Call to function xxx with no prototype": Es fehlt eine #include-Datei
Abhilfe: Online-Hilfe mit Cursor auf Name der Funktion und [Ctrl+F1] drücken, dann gibts Beschriebung zum jeweiligen Befehl, auch welche #include-Datei gebraucht wird.
c | = | a | + | b | ; | |
int | int | double | Datentyp | |||
int | double | Zwischenergebnis | ||||
rechts vom Komma: Bei der Zuweisung wird gegebenenfalls
in den Typ der Variable konvertiert, auf den zugewiesen wird (hier a).
In dem Beispiel oben werden also die Nachkommastellen falls vorhanden-
abgeschnitten und der Typ double auf die Größe vom Typ
int abgeschnitten.
Zuweisung | ||||||||||||
a | = | a | * | b | ; | « | a | *= | b | ; | ||
a | = | a | / | b | ; | « | a | /= | b | ; | ||
a | = | a | % | b | ; | « | a | %= | b | ; | ||
a | = | a | + | b | ; | « | a | += | b | ; | ||
a | = | a | - | b | ; | « | a | -= | b | ; | ||
Welche *.h Dateien
wann benutzen ?
Dateien laden mit #include | |||
<stdio.h> | Standard Ein-/Ausgabefunktionen | ||
Dateifunktionen | printf( ); scanf( ); gets( ); puts( ); getchar( ); putchar( ) | ||
<conio.h> | Console I/O | kein Standard | |
<math.h> | mathemat. Funktionen
(Für die Operatoren nicht nötig) |
sqrt( ); powl( ); atan( ); sin( ); cos( ); usw. | |
<stdlib.h> | Konvertierungen | atoi( ); atol( ); atof( ); | |
Zufallszahlengenerator | |||
Sortieren | |||
dynam. Speicherverwaltung |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
x | = | 3 | * | y | + | 5 | |||||
14 | 3 | 4 | Priorität | ||||||||
|
|||||||||||
|
|||||||||||
|
x | = | 3 | * | ( y | + | 5 ) | |||||||
14 | 3 | 4 | Priorität | ||||||||||
|
|||||||||||||
|
|||||||||||||
|
/*Die erste Klammer ist ein Funktionsaufruf und wird
nicht in der Priorität nach der zweiten Klammer berücksichtigt.
x = 3 + x - 5 + b ;
14 4 4 4 Priorität
links nach rechts
a = b = c = d = 0 ;
rechts nach links
falsch ist: 7 = x ;
Auf eine Konstante kann nicht zugewiesen werden ! Fehlermeldung wäre in dem Fall: "LVALUE required" ("Linkswert" Ausdruck, der links von einer Zuweisung stehen kann « veränderbarer Speicherplatz)
Priorität | Operatoren | |
3 | * / % | |
4 | + - |
W (Wurfweite) y
w = V2 * sin(2*Ñ ) /g
g.w = V2 * sin(2 * Ñ )
V = Wurzel aus g * w /sin(2 * Ñ )
Eingabe: Weite (Meter) und Winkel
V = m/s
Beispiel: y = sin(x) ; y sin des Winkels // x Winkel
Diese Funktionen übernehmen den Winkel nicht
in der Einheit ° (Grad) sondern radiat (rad).
Umrechnung: rad = grad * PI / 180
grad = rad * 180 / PI
Wahrheitswert: TRUE, FALSE
In C gibt es für Wahrheitswert keinen eigenen
Dateityp. Stattdessen wird int verwendet.
nummerischer Wert in int | Wahrheitswert | |
0 | False | |
alles anderen Werte | True | |
0 | 1 |
Beispiel: if( x > 5 ) ...... ;
Wird Programmintern ein TRUE generiert, so wird hierfür die
1 genommen.
Operatoren zur Formulierung von Bedingungen
== gleich; priorität 7
!= ungleich
binäre Operatoren && logisches AND Priorität 11
| | logisches OR Priorität 12
Hinweis: ein logisch-exclusiverer XOR-Operator ist in C nicht implementiert !
Beispiele:
.....
Datentyp für Wahrheitswerte in C : int
als Bedingung kann in C jeder Ausdruck verwendet werden, der einen int liefert.
if ( x ) .... ; « if( x != 0 ) ... ;
if ( ! x) ... ; « if( x == 0 ) ... ;
Achtung: Fehlerquelle !
if ( x = 5 ) .... ; richtig: if ( x = = 5 ) ....
;
Beispiele:
if ( x >= 'A' && x <= 'Z') ..... ; /* liefert für alle Großbuchstaben TRUE */
if ( ! ( x < 'A' || x > 'Z' ) ) .... ; /* entspricht der 1. */
if ( x < 'A' || x > 'Z') .... ; /* liefert für alle außer den Großbuchstaben TRUE */
if ( ! ( x >= 'A' && x <= 'Z' ) ) .....; /* entspricht der 3. */
Nach folgender Regel (de Morgan´sche Regel)
wird die umgekehrte Bedingung erstellt:
Erst ein NOT davorstellen, dann alle Operatoren
in der Klammer umdrehen.
if ( x >= 'A' && x <= 'Z' | x >= 'a' && x<= 'z' ) ... ;
/* liefert TRUE zurück für alle Groß-
und Kleinbuchstaben */
Hinweis:
Werte in Ganzzahltypen werden prinzipiell genau gespeichert, Werte in floating-point Typen sind mit geringen Rundungsfehlern behaftet.
Für jeden floating-point Typ existiert ein Schwellenwert
ò , für
den gilt:
a + ò
> a
float: ò
= 1.192 * 10 -7
double: ò
= 2.220 * 10 -16
long double: ò
= 1.084 * 10 19
if- und if/else Konstruktionen
Beispiel:
main ( )
{
double ug, og, h ;
printf("Untergrenze: ") ; scanf("%lf" , &ug) ;
fflush(stdin) ;
printf("Obergrenze: ") ; scanf("%lf", &og) ;
fflush(stdin) ;
if (ug > og)
{ h = ug ; ug = og ; og = h ; } /* Dreieckstausch über Hilfsvariable h */
printf("3. Wert: ") ; scanf("%lf", &h ) ;
fflush(stdin) ;
if( h >=ug && h <= og )
printf("liegt im Bereich \n") ;
else
printf("liegt außerhalb des Bereichs\n") ;
}
--------------------------
Oft ist auf mehrere Bedingungen zu prüfen, die sich gegenseitig ausschließen. Dafür eignet sich eine if/else-Kette.
Die Bedingungen bei if( ) werden der Reihe nach geprüft.
Es wird in den ersten Anweisungsteil verzweigt, dessen Bedingung ein TRUE
ergibt. War dies der Fall, so wird die Programmausführung nach dem
Durchlaufen des Anweisungsteils hinter der if/else-Kette fortgeführt.
Ergibt keine der Bedingungen bei if( ) den Wert
TRUE, kommt es draruf an, ob die if/else-Kette von einem optionalen else
abgeschlossen wird. Ist das der Fall, so wird die Anweisung oder der Block,
die/der zum optionalen else gehört durchlaufen. Ist das nicht der
Fall, so wird keine der Anweisungen in der if/else-Kette ausgeführt.
Beispiel:
/* Noten.c */
#include <stdio.h>
/* Eingabe Punktzahl -> Ausgabe Noten */
main ( )
{
int n ;
printf("Punktezahl -> ") ; scanf("%d" , &n) ; fflush(stdin) ;
if( n >= 88 && n <= 100) puts("Sehr gut")
;
else
if (n >= 76 ) puts ("gut") ;
else
if (n >= 63) puts( "mit Erfolg") ;
else
if (n >= 51) puts( "ausreichend") ;
else
if (n >= 0 ) puts( "nicht ausreichend") ;
else
puts("Falsche Eingabe") ;
}
Entscheidungen: Die switch/case Kaskade
(siehe Kopie)
reservierte Wörter: switch, case; default
switch( z ) /* z « Selektor-Variable */
Die Selektor-Varaible und die case-Konstante müssen
vom genzzahligen Typ sein. Der Standard schreibt mindestens int vor. Bereiche
von Werten weie [20 ... 50] können nicht angegeben werden, zusammmengesetzte
Datentypen (z.B. Arrays, also auch Strings) sind nicht erlaubt.
(ternär, Priorität 13) Ersetzt eine einfache if/else Konstruktion der Form
if( bed.) anw.1 ;
else anw.2 ; bed. ? anw.1 : anw.2 ;
Beispiel:
float f ;
f <- Wert ;
f >= 0 ? printf("%10.3f + \n", f)
: printf("%10.3f - \n", -f ) ;
Der Konditionaloperator gibt einen Wert zurück, der zugewiesen werden kann. Es ist der Wert, den die Anweisung hinterläßt, die tatsächlich ausgeführt wird.
Beispiel:
int x, y, max ;
x <- Wert ; y <- Wert ;
max = x > y ? x : y ; /* if (x > y ) max = x; else
max = y ; */
Entscheidungskonstruktionen on C/C++ geordnet nach allgemeiner Verwendbarkeit:
Die Operatoren increment ( + + ) und decrement (- - )
Die Operatoren sind unär
Erhöhen, bzw. erniedrigen den Inhalt des Operanden um 1.
Beispiel:
c++ ; «
c = c + 1 ;
Achtung: Es gibt 2 Syntax-Möglichkeiten:
Postfix-Schreibweise C++ ; bzw. C-- ;
Prefix-Schreibweise ++C ; bzw. - - C ;
Der Unterschied in der Wirkungsweise kommt erst zum
Tragen, wenn die increment/decrement-Anweisung in einem Zusammenhang eingebettet
ist:
Postfix | Prefix |
"benutze Inhalt der Variable und erhöhe dann ihren Wert" | "erhöhe den Wert der Variable und erhöhe in dann." |
Beispiel:
int c ;
c = 5 ;
printf("%d \n ", c++) ; /* Gibt am Bildschirm 5 aus und erhöht
dann den Wert von c um 1 /
printf("%d \n ", ++c) ; /* erhöht c um 1 und gibt dann diesen
Wert aus, also 7 */
Laufbedingung | Abbruchbedingung |
abweisend | nicht abweisend |
Jede der Schleifen in C bindet eine Anweisung oder einen Anweisungsblock, der mehrere Anweisungen enthalten kann.
Schleifenkonstruktionen dürfen geschachtelt werden, wobei die innere Schleife vollständig in der äußeren liegen muß
Schleifen und Entscheidungskonstruktionen dürfen
beliebig miteinander kombiniert werden.
Syntax:
while ( bed. ) anw ; /* Eine Anweisung */
while (bed.
{
anw1 ; anw2 ; ) /* Mehrere Anweisungen */
anw3 ; ....... ;
}
Beispiel:
int a ;
i = 'A' ;
while ( i <= 'Z' )
{
printf("%c" , i ) ;
i++ ;
} /* Ende der Schleife */
printf("\n") ;
printf("%c" , i) ; /* Gibt das ASCII-Zeichen aus
nach Z -> [ */
i = 'A' ;
while ( i <= 'Z' ) printf(" %c " , i++ ) ; /*
Ende der Schleife */
printf("\n") ;
for ( ausdr1 ; ausdr2 ; ausdr3 ) anw. /* Eine Anweisung */
for (ausdr1 ; ausdr2 ; ausdr3 )
{
anw1 ; anw2 ; ..... ; /* Mehrere Anweisungen */
anwN ;
}
Beispiel:
for ( i = 'A' ; i <= 'Z' ; i++ )
printf(" %c " , i ) ;
printf("\n") ;
for ( ; ; ) ; /* wiederholt endlos die Leeranweisung
*/
i = 'A' ;
do printf("%c" , i ++ ) ; while (i <= 'Z' ) ;
printf("\n") ;
oder:
i = 'A' ;
do
{
printf("%c" , i) ;
i ++ ;
}
while ( i<= 'Z' ) ;
printf("\n") ;
Printf("Weiter mit [RETURN] ") ;
do /* reagiert nur auf Eingabe von [RETURN] */
i = getch ( ) ;
while ( i != 13) ;
do
i = getch ( ) ; /* bleibt in der Schleife bis zur
Eingabe von 0, 1 oder 2 */
while ( i < '0' || i > '2' ) ;
Printf("Wollen sie .... [j/n] ->") ;
do
i = getch ( ) /* bei Eingabe von j, n, N, J gehts
raus aus der Schleife */
while ( i != 'j' && i != 'J' &&
i != 'n' && i != 'N' ) ;
nach der de Morgan´schen Regel:
while (!( i = = ' j ' || i = = 'J' || i = = 'n' ||
i = = 'N' ) ;
Befehl | vorkommen | Wirkung |
break
(häufig) |
in Schleifen und in switch / case Konstruktionen | Sprung hinter das Ende der unmittelbare umgebenden Schleife bzw. switch / case Konstruktion |
continue
(seltener, weil auch mit if möglich) |
nur in Schleifen | beginne nächsten Schleifendurchlauf sofort. Entspricht einem Sprung zur erneuten Prüfung der Laufzeitbedingung. Bei for Schleifen wird so vorhanden- vorher noch der ausdr3 gemacht. |
Befehl | vorkommen | Wirkung |
exit ( ) | Standardfunktion <stdlib.h>
Kann an beliebiger Stelle im Anweisungsteil aufgerufen werden. |
beendet aktuellen Prozeß |
Syntax für exit ( ) :
Befehl | vorkommen | Wirkung |
goto | nicht oder nur sparsam verwenden ! | Sprung zur angegebenen Marke |
Übungen: