Beispielprogramm P3-1.C
main()
{
printf ("Viel Spass mit C !\n");
}
Erläuterungen zu diesem Programm:
- C-Programme bestehen aus Funktionen, diese sind an den dem Funktionsnamen folgenden runden Klammern zu erkennen
- Funktion main() muß immer vorhanden sein
- sie wird meist am Anfang des Quellencodes plaziert
- die geschweiften Klammern umschließen den Funktionskörper wie z.B. BEGIN und END in PASCAL
- das Ende des Quellencodes muß nicht explizit angegeben werden
- in C gibt es nur Funktionen, keine CALLs
- printf ist eine Funktion zur formatierten Ausgabe auf den Bildschirm
- sie hat hier die Stringkonstante "Viel Spass mit C !\n" als Parameter
- die Zeichenkombination \n steht für das Zeilenendezeichen
- C kennt keine Zeilenstruktur (Ausnahme: innerhalb von Zeichenketten oder #define-Anweisungen)
- Anweisungen sind mit ; zu beenden
Beispielprogramm P3-2.C
main()
{
printf ("Viel");
printf (" Spass");
printf (" mit");
printf (" C !");
printf ("\n");
}
Erläuterungen zu diesem Programm:
gleiche Wirkung wie Programm P3-1.C aber anderes Programm
kein explizites Zeilenendezeichen, daher Verkettung der Ausgabe
das Zeichen \ wirkt als Fluchtsymbol, es dient zur Darstellung von Sonderzeichen:
\t = Tabulatorzeichen \b = Backspacezeichen \" = das Zeichen " \\ = das Zeichen \
Beispielprogramm P3-3.C
/* Beispiel 3 */
/* Umwandlung von Fahrenheit in Celsius
fuer f = 0, 20, ..., 300 */
main()
{
int lower,upper,step;
float fahr,celsius;
lower = 0; /* untere Grenze der Temperaturtabelle */
upper = 300; /*obere Grenze */
step = 20; /*Schrittweite */
fahr = lower;
while (fahr <= upper) {
celsius = (5.0/9.0) * (fahr-32.0);
printf ("%4.0f %6.1f\n",fahr,celsius);
fahr = fahr + step;
}
}
Erläuterungen zu diesem Programm:
- alle Angaben zwischen /* und */ werden als Kommentar behandelt
- Kommentar kann überall im Quellencode stehen wo auch ein Leerzeichen, Tabulatorzeichen oder Zeilentrennzeichen stehen darf, sinnvollerweise schreibt man ihn aber an das Ende einer Zeile und/oder verwendet Kommentarzeilen
- in C müssen alle Variablen vor ihrer Verwendung vereinbart werden
- Vereinbarungen müssen am Anfang eines Blocks vor der ersten Anweisung stehen
- man unterscheidet Deklarationen und Definitionen
- C kennt folgende elementaren Datentypen
char := einzelnes Zeichen (Character)
int := Integerzahlen
float := Gleitkommazahlen
double := Gleitkommazahl mit doppelter Genauigkeit
- zur Qualifizierung dienen dann noch die Zusätze:
short := kleine Integerzahl
long := große Integerzahl
unsigned := ohne Vorzeichen
signed := mit Vorzeichen (Weglasswert)
- die Zeilen :
lower = 0;
upper = 300;
fahr = lower;
stellen Zuweisungen dar, dabei wird im 3.Fall eine Typwandlung von int nach float durchgeführt
- while (fahr <= lower) {
...
}
ist eine von mehreren in C realisierten Kontrollstrukturen, die Anweisungen in den geschweiften Klammern werden nur ausgeführt, wenn der Ausdruck in der Klammer nach while wahr ist
- hängt nur eine einzige Anweisung von der while Bedingung ab, so kann man die geschweiften Klammern auch weglassen:
while (i < j)
i = 2 * j;
- in C gilt generell die Konvention:
gleich 0 := FALSE (FALSCH)
ungleich 0 := TRUE (WAHR)
- die Formulierung 5.0/9.0 gegenüber 5/9 ist notwendig, da wegen der sonst verwendeten Ganzzahlarithmetik 5/9=0 gilt
- dagegen kann man die Zahl 32 als 32 oder 32.0 schreiben, weil C die Verwendung gemischter Typen in Ausdrücken erlaubt; zum Zwecke der besseren internen Dokumentation sollte man in unserem Falle aber 32.0 verwenden (Gleitkommazahlen)
- printf kann mehr als einen Parameter haben und gleichzeitig die Ausgabe formatieren:
printf("%4.0f %6.1f\n",fahr,celsius);
bedeutet:
gibt die Variable fahr im Gleitkommaformat mit insgesamt 4 Stellen ohne Nachkommastellen aus, füge ein Leerzeichen (Blank) ein, gib dann die Variable celsius im Gleitkommaformat mit insgesamt 6 Stellen und einer Nachkommastelle aus und schließe die Ausgabe mit einem Zeilenendezeichen ab
- printf kennt noch andere Umwandlungsformate:
%c := ein einzelnes Zeichen
%d = Integerzahl
%f := Gleitkommazahl
%o := Oktaldarstellung
%s := Zeichenkette
%x := Hexadezimaldarstellung
%% := das %-Zeichen selbst ausgeben
Beispielprogramm P3-4.C
/* Beispiel 4 */
/* wie Beispiel 3 aber mit for-Schleife */
main()
{
int fahr;
for (fahr=0; fahr <= 300; fahr=fahr+20)
printf ("%4.0d %6.1f\n",fahr,(5.0/9.0)*(fahr-32));
}
Erläuterungen zu diesem Programm:
- dieses Programm liefert das gleiche Ergebnis, wie das vorige Beispiel, aber es sieht ganz anders aus
- fahr ist jetzt eine Integerzahl, dies dient nur der Demonstration der %d Umwandlung
- printf akzeptiert auch Ausdrücke für die auszugebenden Parameter
- die for Schleife ist eine weitere in C mögliche Kontrollstruktur, sie hat die Form:
for (Initialisierung; Bedingung; Reinitialisierung)
Beispielprogramm P3-5.C
/* Beispiel 5 */
/* wie Beispiel 4 aber mit #define-Konstanten */
#define LOWER 0 /* untere Grenze der Tabelle */
#define UPPER 300 /* obere Grenze der Tabelle */
#define STEP 20 /* Schrittweite */
main()
{
int fahr;
for (fahr=LOWER; fahr <=UPPER; fahr=fahr+STEP)
printf ("%4.0d %6.1f\n",fahr,(5.0/9.0)*(fahr-32));
}
Erläuterungen zu diesem Programm:
- die Verwendung von symbolischen Konstanten garantiert eine einfache Änderungsmöglichkeit
- symbolische Konstanten werden üblicherweise zur einfacheren Identifizierung in Großbuchstaben geschrieben
- C unterscheidet zwischen Groß- und Kleinschreibung
- nach #define Zeilen steht kein Semikolon, da #define einen Textersatz (also auch mit evtl. Semikolon) bewirkt
- das # muß in der 1. Spalte stehen
- der C-Präprozessor verarbeitet diejenigen Anweisungen, bei denen ein # in der ersten Spalte steht (in unserem Falle hier ist diese Verarbeitung ein Textersatz)
Beispielprogramm P3-6.C
/* Beispiel 6 */
/* ein Kopierprogramm */
#include <stdio.h> /* enthaelt wichtige Konstantendefinitionen */
main()
{
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c=getchar();
}
}
Erläuterungen zu diesem Programm:
- #include bewirkt das Einfügen von Quellencode aus einer anderen Datei
- die Hauptanwendung liegt im Einfügen von sogenannten Header-Dateien, die üblicherweise zu jedem C-Bibliothekssystem dazugehören
- eine solche Headerdatei hat die Dateinamenergänzung .h und enthält Symbole und Vereinbarungen, die bei bestimmten Anwendungen (z.B. Ein-/Ausgabe, Dateiverarbeitung) immer wieder gebraucht werden
- die spitzen Klammern um den Dateinamen bewirken, daß zunächst das "INCLUDE"-Verzeichnis (bei UNIX Systemen meist /usr/lib/include) und erst dann das Arbeitsverzeichnis nach der angegebenen Datei durchsucht wird
- auf verschiedenen Rechnern kann EOF 0 oder -1 sein, daher die Definition von EOF in einer Headerdatei
- c ist als int deklariert, um den Wert EOF abfragen zu können
- getchar ist eine Funktion aus der Funktionsbibliothek, die 1 Zeichen von der Konsole (stdin) einliest
- putchar gibt 1 Zeichen auf die Konsole (stdout) aus
- != bedeutet ungleich
- nach der while Bedingung sind 2 Anweisungen mittels geschweifter Klammern zu einem Block zusammengefaßt
- man hätte das Programm auch noch kompakter so formulieren können
while ((c=getchar()) != EOF)
putchar(c);
die Klammerung ist sehr wichtig sonst wird c der Wert des Vergleiches von getchar() mit EOF und nicht das gelesene Zeichen zugewiesen
Beispielprogramm P3-7.C
/* Beispiel 7 */
/* Programm zum Zaehlen von Eingabezeichen */
#include <stdio.h>
main()
{
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf ("%ld\n",nc);
}
Erläuterungen zu diesem Programm:
- ++nc ist eine Inkrementoperation für die Variable nc, analog ist --nc eine Dekrementoperation
- ++nc und nc++ sind beide möglich, unterscheiden sich aber
- ++nc heißt erst inkrementieren, dann Wert von nc verwenden
- nc++ heißt erst Wert von nc verwenden, dann inkrementieren
- die Formatangabe %ld ist notwendig, da nc ein Long-Integerwert ist
Beispielprogramm P3-8.C
/* Beispiel 8 */
/* wie Beispiel 7, aber mit for-Schleife
und anderer Datentyp fuer den Zaehler */
#include <stdio.h>
main()
{
double nc;
for (nc=0;getchar() != EOF; ++nc)
;
printf ("%.0f\n",nc);
}
Erläuterungen zu diesem Programm:
- die for-Schleife in diesem Fall hat keine abhängige Anweisung, daher das einzelne Semikolon in einer neuen Zeile (wichtig zur Dokumentation)
- die Formatangabe %.0f bewirkt die Ausgabe eine doppelt genauen Gleitpunktzahl ohne Nachkommastellen
Beispielprogramm P3-9.C
/* Beispiel 9 */
/* Programm zum Zaehlen der Eingabezeilen */
#include <stdio.h>
main()
{
int c,nl;
nl = 0;
while ((c=getchar()) != EOF) /* Klammern sind wichtig */
if (c == '\n')
++nl;
printf("%d\n",nl);
}
Erläuterungen zu diesem Programm:
- hier sehen wir eine if Kontrollstruktur, wobei die Bedingung wie bei while in Klammern gesetzt wird
- die if Kontrollstruktur sieht so aus:
if (Bedingung)
Anweisung(en)
else
Anweisung(en)
der else Zweig ist optional
- == bedeutet identisch
- '\n' ist eine Zeichenkonstante, deswegen in Hochkommas eingeschlossen
Beispielprogramm P3-10.C
/* Beispiel 10 */
/* Eingabezeilen, -worte und -zeichen zaehlen */
#include <stdio.h>
#define YES 1
#define NO 0
main()
{
int c, nl, nw, nc, inword;
inword = NO;
nl = nw = nc = 0;
while ((c=getchar()) != EOF) {
++nc;
if (c == '\n')
++nl;
if (c==' ' || c=='\n' || c=='\t')
inword = NO;
else if (inword == NO) {
inword = YES;
++nw;
}
}
printf("%d %d %d\n",nl,nw,nc);
}
Erläuterungen zu diesem Programm:
- verbundene Anweisungen wie nl=nw=nc=0; werden von rechts nach links abgearbeitet, sie sollten nach Möglichkeit vermieden werden
- || ist der (logische) ODER-Operator
- && ist der (logische) UND-Operator
- Ausdrücke mit logischen Operatoren werden von links nach rechts bewertet und dann abgebrochen, wenn das Ergebnis feststeht (also der erste Teilausdruck ungleich 0 (bei ODER) oder gleich 0 (bei UND) ist
Beispielprogramm P3-11.C
/* Beispiel 11 */
/* Ziffern, Zwischenraeume und andere Zeichen zaehlen */
#include <stdio.h>
main()
{
int c,i,nwhite,nother;
int ndigit[10];
nwhite=nother=0;
for (i=0; i<10; ++i)
ndigit[i]=0;
while ((c=getchar()) != EOF)
if (c>='0' && c<='9')
++ndigit[c-'0'];
else if (c==' ' || c=='\n' || c=='\t')
++nwhite;
else
++nother;
printf("Zahlen =");
for (i=0; i<10; ++i)
printf(" %d",ndigit[i]);
printf("\n\"White Space\" = %d, andere = %d\n",
nwhite,nother);
}
Erläuterungen zu diesem Programm:
- Vektoren (Felder) werden durch Anhängen von eckigen Klammern an den Variablennamen definiert
- die Feldindizes laufen von 0 bis N-1, sie werden nicht abgeprüft
- das Beispielprogramm gilt nur für Zeichencodes mit lückenlosem Aufeinanderfolgen von Ziffern (sowohl in EBCDIC als auch in ASCII erfüllt)
- char wird intern in int gewandelt, deshalb ist der Ausdruck
c-'0'
so einfach möglich
- Verkettungen von if und else sollte man so schreiben:
if oder if
else else if
if
else else
Beispielprogramm P3-12.C
/* Beispiel 12 */
/* die Funktion X hoch N */
main()
{
int i;
for (i=0; i<10; ++i)
printf("%d %d %d\n",i,power(2,i),power(-3,i));
}
power(x,n) /* x hoch n, n>0 */
int x,n;
{
int i,p;
p=1;
for (i=1; i<=n; ++i)
p = p * x;
return(p);
}
Erläuterungen zu diesem Programm:
- hier haben wir zum ersten Mal eine "richtige" Funktion
- eine Funktion hat immer die Form:
Name(Parameterliste,optional)
Parameterdeklarationen,optional
{
Vereinbarungen
Anweisungen
return Funktionswert,optional
}
- die Parameternamen sind nur lokal bekannt
- die Parameterwerte sind durch die Funktion nur lokal nicht aber mit Wirkung für die aufrufende Funktion veränderbar
- die return Anweisung bewirkt einen Rücksprung mit der Übergabe des Funktionswertes, die Klammern um den Funktionswert sind syntaktisch nicht notwendig, aber üblich
- fehlt return, dann erfolgt der Rücksprung nach der letzten schließenden geschweiften Klammer, der Funktionswert ist dann unbestimmt
Beispielprogramm P3-13.C
/* Beispiel 13 */
/* Wie Beispiel 3, aber mit Einlesen der
Grenzen und der Schrittweite */
#include <stdio.h>
main()
{
int i;
int lower,upper,step;
float fahr,celsius;
i=0;
while (i != 2) {
printf("Bitte die Grenzen fuer die Berechnung in \
der Form \"untere - obere\" angeben\n");
i=scanf("%d - %d",&lower,&upper);
if (i != 2 || upper<=lower) {
printf("\n Falsche Eingabe \07\n");
i = 0;
}
}
i=0;
while (i != 1) {
printf("Bitte die Schrittweite eingeben: ");
i=scanf("%d",&step);
if (i != 1 || step <= 0) {
printf("\n Falsche Eingabe \07\n");
i = 0;
}
}
fahr = lower;
while (fahr <= upper) {
celsius = (5.0/9.0) * (fahr-32.0);
printf ("%4.0f %6.1f\n",fahr,celsius);
fahr = fahr + step;
}
}
Erläuterungen zu diesem Programm:
- wir haben hier das gleiche Programm wie in Beispiel P3-3.C, allerdings werden hier einige Daten interaktiv eingelesen
- das Einlesen wird von der Funktion scanf bewerkstelligt
- sie hat die gleiche Formatsteuerung wie printf
- die Parameter müssen aber Adressen sein (Warum?)
- & ist der Adressoperator, Ergebnis ist die Adresse des Objekts
- Funktionswert von scanf ist die Anzahl erfolgreich eingelesener Parameter
- alle Angaben in den Anführungsstrichen von scanf, die nicht zu Formatangaben gehören, müssen genauso eingegeben werden
- Strings dürfen über das Zeilenende hinausgehen, wenn unmittelbar vor dem Zeilenende ein \ steht
- \" gibt " aus
- \07 gibt das ASCII-Zeichen mit dem Oktalcode 07 (=BELL) aus