C - Kurs Hadersbeck

Werbung
C - Kurs
Hadersbeck
Literaturhinweise:
Kernighan, Ritchie : The C Programming Language, Prentice Hall, 1988
Darnell, Margolis : Software Engineering in C, Springer Verlag, 1988.
1
1.
Einleitung
1.1.
Historische Bemerkungen
Entwickelt von Kernighan, Ritchie (AT&T Bell Laboratoriers)
Relativ geringer Sprachumfang : Kontrollstrukturen, wenig Variablentypen, Funktionen, Modulares
Programmieren, Kein Input Output.
Erste Version 1983 von C veröffentlicht in "The C Programming Language" (Kernighan, Ritchie) (1983)
UNIX geschrieben in C.
Neuere ANSI Version (1988) wird zum Standard (Besseres Funktionen Konzept, definierte Library),
veröffentlicht in "The C Programming Language" , second Edition (Kernighan, Ritchie) (1988)
2.
Grundlagen
2.1.
Allgemeine Programmstruktur
Ein C-Programm kann aus beliebigen Funktionen, die über verschiedene Module verteilt sind bestehen. Eine
Funktion innerhalb des Programms entspricht der Hauptfunktion und heißt main(). Sie stellt den
Programmeinsprungspunkt dar.
Jedes C-Programmodul hat folgende Struktur :
[ Praeprozessor Direktiven ]
[ Typ - Deklarationen ]
[ Definition und Deklaration von Variablen (globale Variablen) ]
[ Deklaration von Funktionen ]
Definition von Funktionen (nur eine Funktion wird main genannt )
Jede Funktion hat folgende Struktur :
[ Funktionstyp ]
Funktionsname ( [
Parameter 1 ,...,
Parameter n ] )
Funktionsrumpf
Ein Funktionsrumpf hat folgende Struktur :
{
[ Deklarationen von Variablen ]
Statements
}
2
Beispiel :
Funktion mit Hauptprogramm
Praeprozessor - Direktiven
funktion
{
/* Anweisungen der Funktion_1 */
}
main ()
{
/* Hauptprogramm */
}
dazu Programmbeispiele :
1. Programm :
#include <stdio.h>
hallo ()
{
puts("Hallo");
}
main ()
{
hallo();
}
2. Programm :
#include <stdio.h>
#define readint(Z) scanf("%d",&Z)
/* Minimum, Produkt
berechnet die kleinere und das Produkt zweier Zahlen, die der Benutzer
eingegeben
hat.
*/
int mult (int a, int b)
{
return (a*b);
}
main()
{
int kleiner,prod;
int zahl1, zahl2;
/* das Ergebnis */
/* Eingabe Werte */
/* prompt fuer die Benutzereingabe */
puts(" Bitte geben Sie die erste Zahl ein ");
readint(zahl1);
puts(" Bitte geben Sie die zweite Zahl ein ");
readint(zahl2);
/* suche die kleinere Zahl */
if (zahl1 < zahl2)
kleiner = zahl1;
else
kleiner = zahl2;
printf("Die kleinere der Zahlen %d und %d ist :%d\n",zahl1,zahl2,kleiner);
3
/* berechne das Produkt */
prod = mult(zahl1,zahl2);
printf("Das Produkt der Zahlen %d und %d ist : %d \n",zahl1,zahl2,prod);
}
2.1.1. Aufgaben
1. Kreieren Sie in Ihrem Homeverzeichnis einen Ordner Uebung1
2. Implementieren Sie in diesem Ordner das Programm 1 und Programm 2 aus diesem Kapitel.
Der Source-Filename für Programm 1 ist : prog-1.c
Der Source-Filename für Programm 2 ist : prog-2.c
2. Schreiben Sie ein Programm addiere, das drei ganze Zahlen einliest, die größte und die Summe der drei
Zahlen ausgibt.
Dazu verwenden Sie die Funktion add :
int add(int a, int b, int c)
{
return (a+b+c)
}
2.2.
Kommentare in Programmen
Kommentare können an beliebiger Programmstelle stehen und werden von den Zeichen
/* und */ eingerahmt. Die Länge der Kommentare ist unbeschränkt, wobei die Kommentare jedoch nicht
verschachtelt sein dürfen.
2.3.
Konstanten
2.3.1. ganze Zahlen
integer Konstanten : 1234
long integer : suffix l oder L 234L,
oktal Zahl : '\013' oder prefix 0
(Hochkomma auf der Appletastatur : alt ´ (links von der DELETE Taste) )
hexadezimal Zahl : '\xhh' oder prefix 0x
unsigned integer : postfix u oder U
2.3.2. floating Zahlen
float Konstanten : 2.3, 1e-2
2.3.3. Zeichen und Zeichenketten
string Konstanten : "abc"
character Konstanten : 'c'
4
2.4.
Variablen
2.4.1. Was sind Variablen
Eine Variable besteht aus zwei Teilen : Einem Namen und einem Objekt. Jede Variable zeigt genau auf ein
Objekt und kann zu einem Zeitpunkt nur einen Wert annehmen.
x
=
Variablenname
10
Wert der Variable
int x;
Adresse
Adresse
Adresse
Beispiel :
Häuser werden mit Hausnummern verwaltet. Der Variablenname entspricht der Hausnummer.
Jede Hausnummer zeigt auf ein Haus (Objekt) und kann zu einem Zeitpunkt nur einen Wert
(Nummer) annehmen. Das Objekt steht an einer bestimmten Stelle (Speicheradresse), die sich
nicht ändern kann.
5
2.4.2. Regeln für Variablen in C
–
–
–
-
Jede Variable muß vor dem Gebrauch deklariert werden
Variablennamen beginnen mit Buchstaben
Groß/Kleinschreibung ist signifikant
Namen sollten nicht mit Underscore beginnen (reserviert für Systemvariablen)
31 Buchstaben sind signifikant bei lokalen Variablen
2.4.3. Grundtypen von Variablen
2.4.3.1.
Ganze Zahlen
int
... Integer, implementationsabhängig 16, 32 oder 64 Bit
short
... Integer, 16 Bit
long
... Integer, 32 oder 64 Bit
unsigned int, unsigned short, unsigned long ... kein Vorzeichen
2.4.3.2.
Zeichen
char
unsigned char
2.4.3.3.
... Character 7 Bits
... Character 8 Bits
enum
enum
... Aufzählung einer Menge durch ihre Symbole
enum boolean { YES, NO};
2.4.3.4.
float
2.4.3.5.
double
floating
... Reelle Zahl, 32 Bit
double
... Reelle Zahl, 64 Bit
6
2.4.4. Deklaration von Variablen
Jede Variable muß mit ihrem Namen und ihrem Typ vor dem Gebrauch definiert werden: Daraufhin reserviert
der Kompiler Speicherplatz für sie. Die Definition einer Variablen nennt man Deklaration.
Bei einer Deklaration wird der Typ und die mit Komma getrennten Namen der Variablen angegeben.
Variablen können außerhalb oder innerhalb von Funktionen, oder am Anfang eines Blocks deklariert werden.
Beispiel :
int lower;
float x,y;
char esc;
2.4.5. Lebensdauer von Variablen
Die Lebensdauer einer Variable ist abhängig von der Deklarationsstelle.
Liegt die Deklarationsstelle :
1. Fall : außerhalb einer Funktion (globale Variable)
Lebensdauer innerhalb aller Funktionen des gesamten Programms.
2. Fall : innerhalb einer Funktion (lokale Variable)
Lebensdauer innerhalb der Funktion
3. Fall : innerhalb eines Blocks
Lebensdauer innerhalb des Blocks
2.4.6. Gültigkeit von Variablen
Die Gültigkeit einer Variable entspricht solange der Lebensdauer der Variablen, bis nicht innerhalb einer
Funktion oder eines Blocks eine Variable mit dem gleichen Namen definiert wird.
Beispiel :
#include <stdio.h>
#define readint(Z) scanf("%d",&Z)
int a,b,c,d;
int add(int a,b)
{
int c;
c = a + b;
return c;
}
main()
{
int c;
puts( " Bitte geben Sie zwei Zahlen ein");
readint(a); readint(b);
c = add(a,b);
printf(" Die Addition lautet = %d\n",c);
}
7
2.4.7. Schlüsselwörter
Folgende Schlüsselwörter sind reserviert und dürfen nicht als Variablennamen verwendet werden :
auto
break else
case
char
const float
continue
default
do
double
long
enum
extern
short
for
goto
if
int
switch
register
return
unsigned
signed
sizeof
static
struct
typedef
union
void
volatile
while
2.4.8. Initialisierung von Variablen
Variablen können bei der Deklaration auch Initialisierungswerte zugewiesen werden.
Beispiel :
char esc = ’\\’;
int grenze = MAXLINE + 1;
int upper=100, abc[100];
float x,y,z=1.0e-5;
2.4.9. Zuweisen von Werten an eine Variable
lvalue = rvalue oder
lvalue <op> = rvalue ist äquivalent zu
lvalue = value(lvalue) <op> rvalue
Achtung :
lvalue hat : Typ, Adressenklasse, Namen, Adresse
rvalue hat : Typ, Namen, Wert
Beispiel :
x = 2 + 3;
x += 1;
entspricht
x = x + 1;
8
2.4.10. Konditionale Zuweisung
expr1 ? expr2 : expr3 entspricht :
if expr1 then expr2 else expr3;
Beispiel :
z = (a>b) ? a : b
entspricht :
z = max(a,b)
oder
if (a>b) z=a; else z=b;
2.4.11. Funktionen zum Einlesen und Ausgeben von Variablenwerten
Zum Einlesen von Variablenwerten gibt es die Funktion
scanf(" Kontrollstring ",Adresse_Variable1,Adresse_Variable2 .... )
Beim Einlesen muß die Adresse der Variable in scanf eingetragen werden (& Operator vor dem
Variablennamen).
Zum Ausgeben der Werte von Variablen gibt es die Funktion
printf(" Kontrollstring ",Variable1,Variable2 .... )
Im Kontrollstring wird der Text der Zeile und die Formatierungsanweisung (% Operator für
Formatierungsbuchstaben) für jede Variable angegeben. Soll am Ende der Zeile ein Zeilenvorschub eingefügt
werden, muß dafür ein explizites Zeilenvorschub Zeichen eingefügt werden.
Die wichtigsten Formatierungsbuchstaben sind :
d für dezimal Zahlen
f für reelle Zahlen
c für Buchstaben
9
Beispiel :
int m;
float x;
char ant;
printf("Bitte geben Sie eine ganze Zahl ein >>>");
scanf("%d",&m);
printf("Die Eingabe war %d\n",m);
printf("Bitte geben Sie eine reelle Zahl ein >>>");
scanf("%f",&x);
printf("Es wurde die ganze Zahl %d und die reelle Zahl %f
eingegeben\n",m,x);
printf("Es wurde die ganze Zahl >>>%d<<< und die reelle Zahl >>>%f<<<
eingegeben\n",m,x);
printf("Weitermachen y/n >>>");
fflush(stdin);
scanf("%c",&ant);
2.4.12. Aufgaben
1. Schreiben Sie ein Programm das eine ganze und eine reelle Zahl einliest. Geben Sie das Quadrat und die
Summe der Zahlen aus.
2. Schreiben Sie ein Programm, das einen Buchstaben einliest und den Buchstaben mit seinem ASCII -Wert
ausgibt. Ändern Sie den Buchstaben jenachdem in seinen äquivalenten Groß/Kleinbuchstaben.
10
2.5.
Operatoren
2.5.1. Arithmetische Operatoren
Binäre arithmetische Operatoren sind :
+
*
/
/
%
plus
minus
Multiplikation
Division, reellwertig
Division, ganzzahlig
Modulo Operator
2.5.2. Typenkonvertierung bei arithmetischen Ausdrücken
In einem arithmetischen Ausdruck mit Variablen verschiedener Datentypen wird eine Variable mit
schwächerem Typ automatisch in einen stärkeren konvertiert :
schwach
char -> int
->
->
stark
float -> double.
Explizite Konvertierung muß mit dem cast Operator erzwungen werden. Der cast Operator besteht aus den
Zeichen ( und ), den gewünschten Type eingeschlossen.
Beispiel :
x = (int) y; cast operator mit dem Typen int
int a,b;
(a/b)*b + (a%b) == a;
float kreisfläche(float radius)
{
float pi = 3.14;
return 2 * radius * radius *pi;
}
11
2.5.3. Aufgabe
Welches Ergebnis und welcher Typ wird erzwungen:
short a = 10;
long b = 1L;
float x = 9.0;
double y = 2.3d-2;
a
b
b
x
x
y
=
=
=
=
=
=
(short) b;
______
a;
______
a + x;
______
sqrt ((double) x); ______
y + x;
______
a + b + x + y
______
__________
__________
__________
__________
__________
__________
2.5.4. Relationale und Logische Operatoren
Es gibt die logischen Werte : wahr (jede Zahl ungleich Null) und falsch (nur die ganze Zahl Null).
logische Operatoren sind :
<
<=
>
>=
==
!=
&&
||
!
kleiner
kleiner gleich
größer
größer gleich
gleich
ungleich
und
oder
nicht
Achtung :
Die Priorität von && ist größer als die von ||, sowohl && als auch || haben aber eine niedrige Priorität als > <,
>= und <= (z.B. x < y && y < x )
Die Negation ( ! ) ist einstellig und konvertiert TRUE (nicht Null) in FALSE (Null) und FALSE (Null) in
TRUE (nicht Null).
Komplexe logische Ausdrücke werden von links nach rechts abgearbeitet, die Abarbeitung ist beendet, wenn
das Ergebnis bestimmt ist.
Beispiel :
if (j < MAX && ((c=getchar()) != ’\n’))
if ((1<lim-1) || (!valid) && (x!=4)) x=0
12
2.5.5. Die Wahrheitstabelle bei logischen Ausdrücken
int p,q;
p
q
p && q
p || q
! p
———————————————————————————————————————
0
0
0
0
1
0
1
0
1
1
1
0
0
1
0
1
1
1
1
0
2.5.6. Aufgabe
Was ist der Wert :
2 == 7
_____
1 >= 0
_____
4 > 4
_____
1 = 2
_____
Beispiel :
float reziprokwert(float x)
{
if (x != 0)
return 1/x;
else
puts(" Achtung Eingabewert ist gleich Null")
}
13
2.5.7. Increment und Decrement Operatoren
++
--
addiert eins auf eine Variable,
subtrahiert eins von einer Variable.
++ und -- können bei Variablen als postfix und als prefix verwendet werden, haben aber dann bei der
Auswertung des Ausdrucks unterschiedliche Bedeutungen.
als prefix : verändere den Wert der Variable und verwende den neuen Wert im Ausdruck
als postfix: verwende zuerst den Wert der Variable innerhalb des Ausdrucks und verändere ihn dann.
Beispiel :
int a = 1;
b = ++a;
Der Wert von a ist 2
Der Wert von b ist 2
int a = 1;
b = a++;
Der Wert von a ist 2
Der Wert von b ist 1
2.5.8. Aufgabe
Was ist der Wert des Ausdrucks :
int j = 0,m=1,n=1;
x = m++ - --j;
___________
m += ++j +2;
___________
j = m++ * m++;
___________
14
2.5.9. Arithmetische Zuweisungsoperatoren
Operator
Zuweisung
Additionszuweisung
Subtrakt. Zuweisng.
Multipliz. Zuweis.
Divisions Zuweisung
Modulo Zuweisung
Symbol
=
+=
-=
*=
/=
%=
Form
a=b
a += b
a -= b
a *= b
a /= b
a %= b
Operation
Speichere den Wert von b in a
Speichere den Wert von a+b in a
Speichere den Wert von a-b in a
Speichere den Wert von a*b in a
Speichere den Wert von a/b in a
Speichere den Wert von a%b in a
Achtung bei Zuweisungen, wenn die Priorität von Operatoren ins Spiel kommt.
Beispiel :
a = a * 3 + 4;
ist ungleich zu
a *= 3 + 4;
2.5.10. Aufgaben
Welche Werte werden bei folgenden Ausdrücken berechnet :
int m = 3,n= 4;
float x = 2.5,y=1.0;
a)
m +=n+x-y;
____________
b)
m /= x+n+y;
____________
c)
m %= y+m;
____________
d)
x+= y -=m;
____________
2.5.11. Bitweise Operatoren
& (bitwise AND), | (bitwise inclusive OR),
^ (bitwise exclusive OR), << left shift, >> right shift,
~ (one komplement),
z.B. : ausblenden von Bits : n = n & 0177;
z.B. : setzen von Bits : n = n | 0101;
z.B. : shift von Bits : 007 << 3 ist 070;
07 >> 1 ist 03
15
2.5.12. Prioritäten der Operatoren
Innerhalb von Ausdrücken gelten folgende Prioritäten bei der Auswertung des Ausdrucks. Je höher der Wert,
desto früher wird der Operator ausgewertet.
Level
Operatoren
Assoziativität
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
()
[] -> .
! ~ ++ -- + - * & (type) sizeof
+
*
/ %
>> <<
<
<= > >=
== !=
&
^
|
&&
||
?:
= += -= *= /= %= &= ^= |= <<=
,
links nach rechts
rechts nach links
links nach rechts
links nach rechts
links nach rechts
links nach rechts
links nach rechts
links nach rechts
links nach rechts
links nach rechts
links nach rechts
links nach rechts
rechts nach links
rechts nach links
links nach rechts
Beispiel :
a == b && x || !y
(a == b) && (x || !y)
( x=putchar() != EOF)
( (x=putchar()) != EOF)
16
>>=
2.5.13. Aufgaben
1. Welche Werte werden von folgenden Programmen ausgedruckt ?
#include <stdio.h>
#define readint(Z) scanf("%d",&Z)
#define readfloat(Z) scanf("%f",&Z)
int arith (void)
/* 1. Programm :
Arithmetik */
{
int a,b,c,d;
int erg;
puts(" Geben Sie vier ganze Zahlen ein \a: ");
readint(a); readint(b); readint(c); readint(d);
erg = a + b;
printf(" a + b = %d\n",erg);
erg = a / b;
printf(" a / b = %d\n",erg);
erg = a % b;
printf(" a mod b = %d\n",erg);
erg = c++;
printf("Nach erg = c++ ist der Wert von erg = %d, von c = %d
\n",erg,c);
erg = --a;
printf("Nach erg = --a ist der Wert von erg = %d, von a = %d
\n",erg,a);
a += 2;
printf(" Nach a += 2 ist der Wert von a = %d\n",a);
}
int logik (void)
/* 2. Programm
Logische Ausdruecke */
{
int a,b,c,d;
float x;
puts(" Geben Sie vier ganze Zahlen ein : ");
readint(a); readint(b); readint(c); readint(d);
if ( b != 0 )
{
x = a/b;
printf(" Der Reziprokwert = %f\n",x);
};
if ( a==b )
puts( " a ist gleich b ");
else
puts(" a ist ungleich b");
if ( a != b && ( a != c || a != d) )
printf( "jawohl \n");
if ( a != b + c )
printf(" a != b + c \n");
}
main (void)
{
arith();
logik();
}
17
2. Schreiben Sie ein Programm, das eine ganze Zahl einliest und ausdruckt ob die Zahl gerade oder ungerade
ist.
3. Schreiben Sie ein Programm das eine ganze Zahl einliest, die Quersumme berechnet und ausgibt. Das
Programm soll auch die Oktal und Hexadezimaldarstellung der Zahl ausgeben Hinweis :
(Formatierungsanweisung)
4. Schreiben Sie ein Wechselkursprogramm für französische Francs.
Das Programm liest den DM Betrag bzw. Francs Betrag ein und berechnet den Wert in der jeweils anderen
Währung.
Der aktuelle Kurs : 100 Francs kosten 29.129 DM
18
Strukturierung von Programmen
2.6.
Kontrollstrukturen
2.6.1. Statements und Blöcke
Jeder Ausdruck, abgeschlossen von einem Semikolon ist ein Statement. Somit ist das Semikolon kein
Trennsymbol sondern das Abschlußzeichen eines Statements.
Mehrere Statements können mit geschweiften Klammern zu einem Block zusammengefaßt werden. Der Block
(=Block-statement) gilt nach außen wie ein Statement und wird nicht mit einem Semikolon abgeschlossen.
Es gibt folgende Statements :
expression-statement
compound-statement
selection-statement
iteration-statement
jump-statement
labeled-statement
2.6.2. expression statement
Dem expression statement entsprechen Wertzuweisungen, Wertvergleiche oder Funktionsaufrufe.
Expressions werden sequentiell der Reihe nach ausgewertet und von einem Semikolon abgeschlossen. Die
leere expression heißt Nullstatement.
Beispiel :
x = 1;
i <= a;
a = b + x;
;
2.6.3. compound statement
Die geschweiften Klammern gruppieren statements zu einem compound statement (=Block). Innerhalb eines
compound statements können Variablen deklariert werden. Die Lebensdauer der Variablen ist nur auf diesen
Block geschränkt.
Beispiel :
{
}
int a;
a=x;
/* Hier kein Semikolon notwendig, da Block-statement */
oder :
if (a==0) { b=1; c=1; d=1; printf(“%d”,i);
oder :
if (a==0) { int i;
}
i= a + 1; printf(“%d”,i); }
19
2.7.
selection-statements
2.7.1. selection statment : if , if - else
if (expression)
statement
if (expression)
statement1
else
statement2
Das if statement testet den numerischen Wert der Bedingung (expression). Falls der Wert ungleich Null ist
(TRUE Fall), wird statement1 ausgeführt.
Es wird nur ein einziges statement nach der Bedingung ausgeführt. Sollen mehrere statements
zusammengefaßt werden, so müssen sie mit geschweiften Klammern geklammert werden.
Bei geschachtelten if .. else gehört das else immer zum näheren if.
Achtung :
expression muß immer in runden Klammern eingschlossen werden.
Beispiel :
if (i==2)
puts("i ist gleich zwei");
else
puts(" i ist ungleich zwei") ;
oder
if ((i==2) || (j!=0))
{ puts(" Der Fall ist eingetreten");
i = 3; }
else
puts(" Ja du Glückspilz ");
Achtung, folgendes ist zulässig :
Ausdruck
if (i=2)
if (++i)
if (i=j<n)
if (i)
if (2)
Bedeutung
Zuweisung an i, dann Test : immer true
Erhöhen des Wertes von i, dann Test
Zuerst errechnen und zuweisen des Wertes an i, dann test ob i TRUE (!= 0) oder
FALSE (=0)
Test ob i TRUE (!= 0) oder FALSE (=0)
immer TRUE (!= 0)
20
2.7.2. selection-statement : switch
switch (expression)
{
case constant-expr: statements1
case constant-expr: statements2
default : statementsn
}
Jeder Label hat eine oder mehrere ganzzahlige Konstanten oder Konstanten Ausdrücke. Entsprechend dem
Wert von expression werden sequentiell alle case constant-expr. ausgewertet und verglichen, ob sie mit dem
Wert übereinstimmen. Bei Übereinstimmung werden die nachfolgenden statements ausgeführt und beim
nächsten case Statement weiter getestet. Soll die Abarbeitung der sequentiellen Tests nach der Ausführung
eines statements abgebrochen werden, so muß dieses statement mit break abgeschlossen werden. Die
Abarbeitung wird dann hinter dem gesamten switch statement fortgesetzt.
Wird keine Übereinstimmung zwischen dem Wert von expression und constant-expr. gefunden, so wird auf
einen eventuell vorhandenen default Fall verzweigt.
Beispiel :
switch (c)
{
case ´0´
case ´2´
case ´2´
default
}
2.8.
: case ´1´ :
:
: case ´3´:
:
puts("0,1"); break;
puts("2");
puts("2,3");
puts(" Nichts davon");
Iteration statements
2.8.1. iteration statement : while
while (expression)
statement
Solange expression TRUE (ungleich Null) ist , wird statement ausgeführt. Es wird genau ein statement
ausgeführt. Sollen mehrere statements ausgeführt werden, müssen sie zu einem compound-statement
zusammengefaßt werden.
Statement wird solange wiederholt, bis der Wert von expression FALSE (gleich Null) ist.
21
Beispiel :
int while_1(void)
{
int num;
puts("Gib den Countdown Wert ein >>>");
readint(num); /* Achtung bei Endlosschleifen */
while ( num > 0 )
{
num --;
printf(" Countdown laeuft >>%d<<\n",num);
};
printf(" Start \n");
}
Achtung vor Unendlichschleifen :
i = 5;
while (i) ;
i --;
while (i > 0)
printf(" Countdownwert ist = %d\n",i);
i--;
2.8.2. iteration statement : for
for (expr1; expr2; expr3)
statement
expr1 : Wird vor dem Durchlauf der Schleife ausgeführt (Initialisierung)
expr2 : Testbedingung der Scheife : Wiederholung falls expr2 ungleich Null
expr3 : Wird nach einem Durchlauf von statement ausgeführt (Increment)
entspricht :
expr1;
while (expr2)
{
statement;
expr3;
}
Achtung : Im Gegensatz zu anderen Programmiersprachen ist die for Schleife bei C viel flexibler, da die
Komponenten expr1, expr2, expr3 einer for loop beliebige Ausdrücke sein können, deren Werte auch
innerhalb der Komponenten verändert werden können.
22
Beispiele :
Es dürfen auch expr's der for Schleife fehlen :
Die endlos Schleife :
for (;;) ;
Der Index einer for Schleife muß nicht unbedingt ein ganzzahliger Wert sein :
int for_2(void)
{
char a;
puts(" Die Buchstaben von a bis g lauten : ");
for (a=’a’; a < ’g’; a ++)
printf(" %c ",a);
printf("\n");
int for_3(void)
{
float x;
puts(" Die Reihe von x - 1/x lautet : ");
for (x=3; x > 0.00005; x = x - 1/x)
printf(" %6.3f\n ",x);
printf("\n");
}
for (i=0; i<n; i++)
{
printf(" Der Schleifendurchlauf Nummer %d\n",i);
m= n+i;
}
komplexe Ausdrücke in expr1, expr2 und expr3, als Rumpf der for Schleife wird die leere Ausweisung
verwendet. Sämtliche Berechnungen werden innerhalb der for Schleife ausgeführt. Dies ist jedoch ein sehr
komplizierter Programmstil und eigentlich abzulehnen.
for (i=0,j=1,x=10; i=j*2*x; i = i*j,x--) ;
2.8.3. Aufgabe :
Welche Werte werden bei folgendem Programmausschnitt ausgedruckt :
int i,j;
int n,m;
n=m=4;
for (i=0;j<n;i++)
for (j=0;j<m;j++)
printf("Der Matrixindex lautet : i = %d
23
j = %d \n",i,j);
2.8.4. iteration statement : do - while
do
statement
while (expression);
Das statement wird ausgeführt und die expression ausgewertet. Falls die expression TRUE ist (ungleich Null)
wird das statement erneut ausgeführt. Wird expression gleich Null (FALSE) terminiert die Schleife und es
wird hinter das Programm wird hinter dem do statement fortgesetzt.
2.9.
jump statements
2.9.1. jump statement : break
Das break statement stellt ein vorzeitiges exit aus einem for, while, do oder switch statement dar. Das break
statement veranlaßt, die innerste Schleife sofort zu verlassen.
Das continue statement beendet eine Iteration innerhalb einer Schleife und springt direkt zum nächsten
Schleifendurchlauf.
2.9.2. jump statement : goto, label
label :
und goto label;
Es wird empfohlen, auf die Programmierung mit Lables zu verzichten (Spagetticode). Es gibt genügend
Kontrollanweisungen um Sprünge innerhalb des Programms zu vermeiden.
2.10. Die Vor- und Nachteile von for, do und while
Die for Loop wird dann verwendet :
- wenn der Schleifenindex im Vordergrund steht. (z.B. Durchlaufen von Arrays).
- Bei einfachen Interationsschritten
- Falls die Iteration und das Abbruchkriterium eng zusammenhängen
Die while ( ) Loop wird verwendet :
- wenn das Abbruchkriterium im Vordergrund steht
- es soll zuerst getestet werden, bevor die Statements im while Block ausgeführt werden, da sonst Fehler
auftreten könnten (z.B. Arithmetischer Ausdruck um Division durch Null zu vermeiden)
Die do () Loop wird verwendet :
- wenn die Statements im do Block im Vordergrund stehen.
- Es sollen zuerst die Statements ausgeführt werden und dann die Bedingung getestet werden. (z.B : Einlesen
von Abbruchkriterien)
24
Beispiel :
#include <stdio.h>
main()
/* Demonstration of blocks and statements */
{
char in,buffer[10];
int len,i=0;
while ( ( (buffer[i++]=getchar() ) != ’\n’) && (i < 10)) ;
len=i;
for (i=0;i<len;i++)
{
char c;
switch (c = buffer[i])
{
case ’0’:case ’1’:case ’2’:case ’3’:case ’4’:case ’5’ :
case ’6’:case ’7’:
puts(" Die Zahl ist kleiner 8"); break;
case ’8’:case ’9’:
puts(" Die Zahl ist größer 8"); break;
default :
if (( c >= 'A' && c <= 'Z') || ( c >= 'a' && c <= 'z'))
puts(" Wir haben einen Buchstaben");
else
puts(" Wir haben ein Sonderzeichen");
}
}
}
2.10.1. Aufgaben
1. Schreiben sie ein Programm zur Lösung von Gleichungen höheren Grades nach den Newtonschen
Näherung und nach dem Sehnenverfahren: Es sein eine Funktion f(x), und x1 ein Näherungswert für die
Nullstelle f(x), so ist xt eine bessere Näherung der Nullstelle.
(a)
xt = x1
-
f(x1)
------f’(x1)
oder nach dem Sehnenverfahren :
(b)
xt = x1
x1 - x2
- f(x1) * -----------f(x2) - f(x1)
2. Schreiben Sie ein Programm, das bis zu 5 mal eine nur im Programm bekannte Geheimzahl abfagt. Bei
jedem Durchlauf wird dem Benutzer ein neuer Tip gegeben, der einen neuen Hinweis zu dieser Geheimzahl
gibt. Wird die Zahl gefunden, dann werden die Anzahl der Versuche ausgegeben.
3. Schreiben Sie ein Programm, das eine Zahl einliest und in Abhängigkeit der Zahl einen beliebigen Spruch
auf das Terminal ausgibt. Nur bei einer bestimmten Zahl soll das Program terminieren. Verwenden Sie zum
beenden des Programms dazu die Lösung aus Aufgabe 2
25
26
Zugehörige Unterlagen
Herunterladen