C für PICs: Programmablaufsteuerung
zurück
zu C für PICs , C-Compiler , PIC-Prozessoren , Elektronik , Homepage
C für PICs
Grundlagen von C
Variablen
Funktionen
Operationen
Programmablaufsteuerung
Arrays und Strings
Pointer
Strukturierte Typen
PIC-spezifisches
zurück zu C für PICs
Programmablaufsteuerung
Ohne Anweisungen zur Programmablaufsteuerung würden in einem
Programm einfach alle Anweisung nacheinander abgearbeitet werden. Es
gäbe keine Möglichkeit auf veränderte Parameter zu reagieren, das
Programm würde vom Start bis zu seinem Ende jedes mal genau das
gleiche tun. Das wäre natürlich nicht besonders sinnvoll.
Aus diesem Grunde gibt es Anweisungen zur Programmablaufsteuerungen.
Die sorgen dafür, dass bestimmte Programmabschnitte nur unter
bestimmten Bedingungen ausgeführt oder auch mehrfach ausgeführt
werden.
if
Anweisung
Die if-Anweisung sorgt dafür, dass eine Anweisung nur unter einer
bestimmten Bedingung ausgeführt wird.
if (ausdruck)
anweisung1;
Beim Erreichen der if-Anweisung
prüft
der
Prozessor, ob ausdruck einen
von 0 verschiedenen Wert hat. Ist das der Fall (und nur dann) wird
die folgende anweisung1 ausgeführt.
Die gesamte if-Anweisung
wird (wie jede Anweisung) durch ein Semikolon abgeschlossen. Aus
diesem Grund darf hinter (ausdruck)
auch kein Semikolon stehen (denn das wäre schon eine null-Anweisung), sondern erst hinter der bedingt
abzuarbeitenden anweisung1.
Will man die gemeinsame Abarbeitung mehrerer Anweisungen durch eine
if-Anweisung steuern, dann
muss man alle diese Anweisungen durch geschweifte Klammern zu einem
Anweisungsblock zusammenfassen. So ein Klammernblock wird wie eine
einzelne Anweisung betrachtet. Die trennenden Semikolen innerhalb
des Klammernblockes beenden deshalb die if-Anweisung nicht. Der Abschluss der if-Anweisung erfolgt mit der
schließenden Klammer. (Dort ist nun kein abschließendes Semikolon
nötig.)
if (ausdruck)
{
anweisung1;
anweisung2;
anweisung3;
anweisung4;
}
if-else
Anweisung
Die if-Anweisung sorgt dafür, dass in Abhängigkeit von einer
Bedingung genau eine von zwei alternativen Anweisungen ausgeführt
wird.
if (ausdruck)
anweisung1;
else
anweisung2;
Beim Erreichen der if-Anweisung
prüft
der
Prozessor, ob ausdruck einen
von 0 verschiedenen Wert hat. Ist das der Fall, wird die folgende anweisung1 ausgeführt. Falls
aber ausdruck den Wert 0
haben sollte, dann wird stattdessen anweisung2 ausgeführt.
Auch hier kann man wieder anstelle von einzelnen Anweisungen ganze
Blöcke von Anweisungen verwenden, die man dann in geschweifte
Klammern setzen muss.
if (ausdruck)
{
anweisung1;
anweisung2;
anweisung3;
anweisung4;
}
else
{
anweisung5;
anweisung6;
anweisung7;
anweisung8;
}
while
Anweisung
Mit der while-Anweisung
wird eine Schleife solange immer wieder durchlaufen, solange eine
bestimmte Bedingung erfüllt ist.
Am Beginn der while-Anweisung
wird
geprüft, ob ausdruck den
Wert
0 (false) hat. Wenn das der Fall sein sollte, dann wird der Rest der
while-Anweisung
übersprungen. Ist aber ausdruck von
0 verschieden, dann wird die folgende Anweisung oder der folgende
Anweisungsblock abgearbeitet und danach wieder an den Anfang der
while-Anweisung gesprungen. Nun wird wieder ausdruck getestet ...
while (ausdruck)
anweisung1;
while (ausdruck)
{
anweisung1;
anweisung2;
}
Beispiel:
Das folgende ist eine Endlosschleife in der main-Funktion.
void main(void)
{
while (1)
{
anweisung1;
anweisung2;
.....
.....
}
}
do-while
Anweisung
Die do-while-Anweisung
entspricht der while-Anweisung,
allerdings
wird
die Schleife auf jeden Fall mindestens einmal durchlaufen.
Die Anweisungen der do-while-Schleife
werden
abgearbeitet,
und danach wird
der Wert von ausdruck geprüft.
Ist dieser von 0 verschieden, dann wird wieder an den Anfang der do-while-Schleife gesprungen.
do
{
anweisung1;
anweisung2;
}
while (ausdruck)
for
Anweisung
Mit der for-Anweisung kann
man eine Programmschleife festlegen, und bestimmen, wie oft sie
durchlaufen werden soll.
Die for-Anweisung sieht in ihrer einfachsten Form so aus:
for (initialisierungsanweisung; ausdruck;
schleifenanweisung);
In den runden Klammern stehen nacheinander drei Abschnitte.
- Beim Erreichen der for-Anweisung
wird
die
initialisierungsanweisung genau
einmal
ausgeführt.
Dabei wird normalerweise einer Schleifenzählvariable ein
Startwert gegeben. diese Variable (Char oder Integer) muss
vorher definiert worden sein.
- Nun beginnt die eigentliche Schleife. An ihrem Anfang wird
geprüft, ob ausdruck den
Wert
0 hat (false). Ist dass der Fall, dann wird die Schleife nicht
abgearbeitet, und die for-Anweisung
beendet.
Andernfalls
(true) wird die Schleife abgearbeitet. Mit ausdruck wird normalerweise
geprüft, ob die Zählvariable einen Maximalwert überschritten
hat.
- Die Schleife besteht im einfachsten Fall nur aus der schleifenanweisung. In der
Schleifenanweisung wird normalerweise die Zählvariable
incrementiert.
Das Ganze lässt sich als while-Anweisung wie
folgt darstellen.
initialisierungsanweisung;
while
(ausdruck)
schleifenanweisung;
Die Schleifenanweisung der folgenden for-Anweisung wird genau 50 mal
durchlaufen:
for (i=0; i<50; i++);
Solange man nur eine einzige Anweisung in der Schleife hat, und
diese auch noch die Zählvariable incrementieren muss, ist so eine for-Anweisung von geringem
Nutzen. Deshalb kann nach der schließenden runden Klammer (anstelle
des abschließenden Semikolons) noch eine Anweisung oder ein ganzer
Anweisungsblock folgen. Die Schleife besteht dann aus dieser
Anweisung/Block, und der abschließenden schleifenanweisung. Zunächst erst mal ein Beispiel
mit einer zusätzlichen Anweisung:
for (initialisierungsanweisung; ausdruck;
schleifenanweisung)
anweisung1;
und wie das mit einer while-Anweisung
aussehen würde:
initialisierungsanweisung;
while
(ausdruck)
{
anweisung1;
schleifenanweisung;
}
Nun noch ein Beispiel mit einem Anweisungsblock in geschweiften
Klammern
for (initialisierungsanweisung; ausdruck;
schleifenanweisung)
{
anweisung1;
anweisung2;
anweisung3;
}
und natürlich das Äquivalent mit der while-Anweisung:
initialisierungsanweisung;
while
(ausdruck)
{
anweisung1;
anweisung2;
anweisung3;
schleifenanweisung;
}
Nun ein etwas weniger theoretisches Beispiel. Es soll die Summe
aller ganzen Zahlen von 1 bis 50 gebildet werden
char i;
integer s=0;
for (i=1; i<51; i++)
s
=
s + i;
break
Anweisung
Die break-Anweisung bricht
die gerade laufende Schleife ab.
Beispiel:
Die folgende for-Schleife
wird durch break vorzeitig
beendet:
void main (void
{
char i;
for
(i=0;
i<50; i++)
{
...
...
if
(i==10) break;
}
}
Die for-Schleife sollte
eigentlich bis i==49 laufen, aber bei i==10 wird break abgearbeitet. Dabei wird
die for-Schleife
abgebrochen.
Das funktioniert auch mit while und
do-while-Anweisungen.
continue Anweisung
Wird in einer Schleife eine continue-Anweisung
abgearbeitet,
dann
werden alle folgenden Anweisungen der Schleife übersprungen, und
sofort zum Test der Schleifenbedingung weitergegangen. Im Gegensatz
zur break-Anweisung
wird
also die Schleife nicht abgebrochen, sondern nur der momentane
Schleifendurchlauf.
Beispiel:
Es wird die Summe aller geraden Zahlen von 0 bis 49 berechnet:
void main (void
{
char i;
int s=0;
for
(i=0;
i<50; i++)
{
if
(i%2) continue;
s
= s + i;
}
}
switch
Anweisung
Mit der if-Anweisung kann
man sich zwischen zwei Anweisungen (oder Anweisungsblöcken) wählen.
Oftmals gibt es aber mehr als nur zwei Alternativen. Das ließe sich
mit ineinander verschachtelten if-Anweisungen
erledigen, eleganter ist aber die switch-Anweisung.
Dabei
wird einer von mehreren Anweisungsblöcken in Abhängigkeit vom Wert
einer Variablen abgearbeitet.
Die Variable steht in Klammern hinter dem Schlüsselwort switch. Die möglichen Werte der
Variable stehen in den einzelnen case-Abschnitten.
Jeder case-Abschnitt
enthält beliebig viele Anweisungen, die abgearbeitet werden, wenn
die Variable den Wert der zugehörigen Konstante hat. Da diese
Anweisungsblöcke nicht durch geschweifte Klammern begrenzt sind,
werden sie durch break-Anweisungen
beendet.
Falls der Wert der Variablen mit keiner der Konstanten
übereinstimmt, wird der default-Abschnitt
abgearbeitet.
Dieser
Abschnitt ist aber optional, er kann also auch fehlen.
switch (variable)
{
case
konstante1:
anweisung01;
anweisung02;
...
break;
case
konstante2:
anweisung10;
anweisung11;
...
...
break;
case
konstante3:
anweisung20;
anweisung21;
...
...
break;
default:
anweisung30;
anweisung31;
...
...
}
null
Anweisung
Die null-Anweisung ist eine
Anweisung die nichts tut. Sie wird durch ein einfaches Semikolon
dargestellt. Damit ist sie ja eigentlich sinnlos, aber sie kann aus
"grammatikalischen" Gründen manchmal nötig sein. Will man z.B. eine
Endlosschleife bauen, aus der der Prozessor nie mehr (oder nur durch
einen Interrupt) herauskommt, so kann man das eigentlich durch eine
while-Schleife machen:
while (1)
Das akzeptiert der Compiler so aber nicht, da eine while-Schleife immer eine
Anweisung enthalten muss. Aber hier gibt es für eine Anweisung rein
gar nichts zu tun. Da bietet sich die null-Anweisung in Form eines Semikolon als Lösung
an.
while (1) ;
Das gleiche gilt z.B. für folgende for-Schleife,
die die Fakultät von 30 ermittelt. Ohne das Semikolon am Ende der for-Zeile, würde der Compiler
das nicht übersetzen.
float f=1;
int i;
for (i=1;
i<=30, f*=i++) ;
return
Anweisung
Sind alle Anweisungen einer Funktion abgearbeitet, dann
springt der Prozessor dorthin zurück, von wo die Funktion gerufen
wurde. Man kann aber eine Funktion auch vorzeitig mit der return-Anweisung beenden. Das
Abarbeiten eines return innerhalb
einer
Funktion
beendet diese sofort.
Die return-Funktion bietet noch ein weiteres wichtiges Feature. Eine
Funktion kann einen Rückgabewert haben. Dieser muss beim Beenden der
Funktion irgendwie festgelegt werden. Das ist die Aufgabe der return-Anweisung. Auf das return-Schlüsselwort darf ein
Ausdruck (z.B. eine Zahl) folgen, die bei Abarbeitung des return an die rufende Funktion
zurückgegeben wird. Aus diesem Grunde kann es auch nötig sein, ein return mit folgendem Ausdruck
hinter die letzte Anweisung einer Funktion zu stellen, um einen Wert
zurückgeben zu können.
-->
weiter
zu
Arrays und Strings
zurück
zu C für PICs , C-Compiler , PIC-Prozessoren , Elektronik , Homepage
Autor: sprut
erstellt: 01.10.2007
letzte Änderung: 23.10.2012