Willkommen bei Bartels
Kontrollstrukturen - Deutsche Version Control Structures - English Version
Bartels

Bartels System GmbH
Bartels
Bartels AutoEngineer
BAE Produktinfo
BAE Preisliste
BAE Downloads
BAE Dokumentation
BAE Installationsanleitung
BAE Benutzerhandbuch
BAE Bibliotheken
User Language Programmierhandbuch
Vorwort
1 Einleitung
2 Sprachbeschreibung
2.1 Einführung in die User Language Programmierung
2.2 Konventionen
2.3 Datentypen und Definitionen
2.4 Ausdrücke
2.5 Kontrollstrukturen
2.5.1 Sequentielle Programm-Elemente
2.5.2 Alternativen
2.5.3 Repetitionen
2.5.4 Kontrollfluss-Steuerung
2.6 Preprozessor-Anweisungen
2.7 Syntaxdefinition
3 Programmiersystem
4 BAE User Language-Programme
A Konventionen und Definitionen
B Index-Variablen-Typen
C Systemfunktionen
BAE Update-Historie
BAE Nächste Version Freigabemitteilungen Vorabinfo
BAE V8.0 Freigabemitteilungen
BAE V7.8 Freigabemitteilungen
BAE V7.6 Freigabemitteilungen
BAE V7.4 Freigabemitteilungen
BAE V7.2 Freigabemitteilungen
BAE V7.0 Freigabemitteilungen
BAE V6.8 Freigabemitteilungen
BAE V6.6 Freigabemitteilungen
BAE V6.4 Freigabemitteilungen
BAE V6.2 Freigabemitteilungen
BAE V6.0 Freigabemitteilungen
BAE V5.4 Freigabemitteilungen
BAE V5.0 Freigabemitteilungen
BAE V4.6 Freigabemitteilungen
BAE V4.4 Freigabemitteilungen
BAE V4.2 Freigabemitteilungen
BAE V4.0 Freigabemitteilungen
BAE V3.4 Freigabemitteilungen
BAE Support
BAE Contrib
BAE Entwickler und Dienstleister
Elektronikentwicklung
Sport
Firmenprofil
Impressum
Bartels :: Bartels AutoEngineer :: BAE Dokumentation :: User Language Programmierhandbuch :: Sprachbeschreibung :: Kontrollstrukturen
Bartels User Language - Programmierhandbuch

2.5 Kontrollstrukturen

Bartels AutoEngineer® Dokumentation

In diesem Abschnitt werden die in der User Language verfügbaren Kontrollstrukturen vorgestellt. Kontrollstrukturen definieren die Reihenfolge, in der die Aktionen eines Programms ausgeführt werden. Grundsätzlich wird in der Bartels User Language - entsprechend den Grundlagen der strukturierten Programmierung - unterschieden zwischen sequentiellen Programm-Elementen, Alternativen und Repetitionen (englisch: CAR - Concatenation, Alternation, Repetition).

 

2.5.1 Sequentielle Programm-Elemente

Anweisungen

Eine Anweisung besteht aus einem Ausdruck (siehe Kapitel 2.4) gefolgt von einem Semikolon (;). Somit sind z.B.

tabulator = '\t' ;
distance = sqrt(a*a+b*b) ;
filename += extension = ".ddb" ;
++ary[i] ;
printf("Part %s ;\n",partname) ;

gültige Anweisungen. Fehlt der Ausdruck vor dem Semikolon, hat die Anweisung also die Form

;

dann liegt liegt der Sonderfall der leeren Anweisung vor. Die leere Anweisung kann in Ausnahmefällen dazu dienen, abhängige Anweisungen (z.B. innerhalb von Schleifen) zu definieren. Grundsätzlich sind sonst aber nur solche Anweisungen sinnvoll, die auch einen Seiteneffekt haben, d.h. irgendeine Variable durch eine Zuweisung verändern oder eine Funktion aktivieren. In der User Language sind allerdings auch Anweisungen zulässig, die keine Seiteneffekte haben wie z.B.

27+16.3;
++11;

Der User Language Compiler erkennt Ausdrücke ohne Seiteneffekte und gibt ggf. entsprechende Warnungen aus.

Anweisungen, die in einer Kontext-Abhängigkeit zu einer Alternative bzw. Repetition (siehe unten) stehen, werden im Folgenden als abhängige Anweisungen bezeichnet.

Blöcke

Ein Block besteht aus einer Folge von Vereinbarungen (siehe Kapitel 2.3.2) und Anweisungen und ist in geschweifte Klammern ({ und }) einzuschließen. Ein Block ist syntaktisch äquivalent zur einfachen Anweisung, kann also auch immer anstelle einer einfachen Anweisung angegeben werden.

 

2.5.2 Alternativen

Alternativen sind Verzweigungen, die die Ausführung bestimmter abhängiger Anweisungen vom Wert eines Ausdrucks abhängig machen.

if- und if-else-Anweisung

Die if-Anweisung hat die allgemeine Form

if (expression)
      statement

Die abhängige Anweisung der if-Anweisung wird nur ausgeführt, wenn der if-Ausdruck einen vom Nullwert (0 bzw. Leerstring für string-Ausdruck) verschiedenen Wert besitzt; andernfalls wird sie übersprungen.

Die if-else-Anweisung besitzt die allgemeine Form

if (expression)
      statement
else
      statement

Zunächst wird der Ausdruck der if-else-Anweisung bewertet. Ist dabei das Resultat vom Null-Wert (0 bzw. Leerstring beim string-Ausdruck) verschieden, wird die erste abhängige Anweisung ausgeführt. Die zweite abhängige Anweisung wird genau dann ausgeführt, wenn das Resultat des Ausdrucks dem Null-Wert entspricht. Die abhängigen Anweisungen der if-else-Anweisung können selbstverständlich wiederum if-else-Anweisungen sein. Damit können auch Verschachtelungen und Ketten von if-else-Anweisungen der Form

if (expression)
      statement
else if (expression) {
      if (expression)
              statement
      }
else if (expression)
      statement
:
else
      statement

gebildet werden. Bei verschachtelten if-else-Anweisungen gehört die else-Anweisung immer zum nächstfrüheren if, für das noch kein else-Teil existiert. In folgendem Beispiel wird die Klasse des aktuell geladenen SCM-Elements abgefragt, und der Wert der Variablen classname wird entsprechend gesetzt:

string classname="SCM ";
if (bae_planddbclass()==800)
      classname+="Sheet";
else if (bae_planddbclass()==801 || bae_planddbclass()==803)
      classname+="Symbol/Label";
else if (bae_planddbclass()==802)
      classname+="Marker";
else {
      classname="***INVALID***";
      printf("No valid element loaded!\n");
      }

switch Anweisung

Die switch-Anweisung sorgt dafür, dass in Abhängigkeit vom Wert eines auf Gleichheit prüfenden Äquivalenz-Ausdrucks bestimmte Anweisungen ausgeführt werden und andere nicht. Die allgemeine Form der switch-Anweisung ist gegeben durch

switch (expression)
      statement

Jeder Anweisung innerhalb der abhängigen switch-Anweisung kann eine beliebige Anzahl von case-Marken der Form

case expression :

oder

default :

vorausgehen. Die zwischen case-Marken befindlichen Anweisungen stehen in Abhängigkeit zu den unmittelbar vorhergehenden case-Marken. Die abhängigen Anweisungen einer case-Marke werden nur dann ausgeführt, wenn der Wert des switch-Ausdrucks mit dem Wert des case-Ausdrucks übereinstimmt; die default-Marke spezifiziert dabei einen beliebigen Wert, d.h. die einer default-Marke folgenden abhängigen Anweisungen kommen immer zur Ausführung. case-Marken selbst haben keinen Einfluss auf die sequentielle Ausführung einer Reihe von Anweisungen; die Ausführung wird fortgesetzt, als ob keine case-Marken vorhanden sind. Um eine switch-Anweisung zu verlassen wird üblicherweise in einem case-Abschnitt die break-Anweisung (siehe auch Kapitel 2.5.4) benutzt. In folgendem Beispiel wird die Klasse des aktuell geladenen SCM-Elements abgefragt, und der Wert der Variablen classname wird entsprechend gesetzt:

string classname="SCM ";
switch (bae_planddbclass()) {
      case 800 :
      classname+="Sheet";
      break;
      case 801 :
      case 803 :
      classname+="Symbol/Label";
      break;
      case 802 :
      classname+="Marker";
      break;
      default :
      classname="***INVALID***";
      printf("No valid element loaded!\n");
      }

 

2.5.3 Repetitionen

Repetitionen sind Anweisungen, mit deren Hilfe Schleifen zur wiederholten, also repetitiven Abarbeitung bestimmter Teile des Programms definiert werden können. Jede repetitive Anweisung verfügt auch über einen Mechanismus zur Überprüfung einer Ende-Bedingung, bei der die Schleifen-Bearbeitung beendet wird. Wird diese Ende-Bedingung nie erreicht, dann spricht man von einer Endlos-Schleife. Läuft ein Programm während der Abarbeitung in eine derartige Endlos-Schleife, dann kann es den Kontrollfluss nicht mehr von sich aus an den Aufrufer zurückgeben. In solchen Fällen liegt in der Regel ein schwerer Programmierfehler vor. Erkennt der User Language Compiler eine Endlos-Schleife, wozu er in bestimmten Fällen in der Lage ist, dann gibt er eine entsprechende Fehlermeldung aus und erzeugt keinen Programm-Code.

while-Anweisung

Die while-Anweisung hat die allgemeine Form

while (expression)
      statement

Die abhängige Anweisung wird solange wiederholt, wie der Wert des while-Ausdrucks ungleich dem Nullwert (0 oder Leerstring für string-Ausdruck) ist. Das folgende Programm dient dazu, die Inhalte von ASCII-Dateien auf dem Bildschirm anzuzeigen:

// ASCII file view
main()
{
      string fname;           // File name
      int fh;                 // File handle
      string curstr="";       // Current input string
      // Set the file error handle mode
      fseterrmode(0);
      // Print the program banner
      printf("ASCII FILE VIEWER STARTED\n");
      // Repeatedly ask for the input file name
      while (fname=askstr("File Name (press RETURN to exit) : ",40)) {
              // Open the input file
              printf("\n");
              if ((fh=fopen(fname,0))==(-1)) {
                      printf("File open failure!\n");
                      continue;
                      }
              // Get the current input string
              while (fgets(curstr,128,fh)==0)
                      // Print the current input string
                      puts(curstr);
              // Test on read errors; close the file
              if (!feof(fh) || fclose(fh))
                      // Read or close error
                      break;
              }
}

Die continue-Anweisung (siehe auch Kapitel 2.5.4) wird in obigem Beispiel verwendet, um wieder an den Beginn der while-Anweisung zu springen; die break-Anweisungen (siehe auch Kapitel 2.5.4) dienen dazu, im Fehlerfall die while-Anweisung zu verlassen.

do-while-Anweisung

Die do-while-Anweisung hat die allgemeine Form

do
      statement
while (expression);

Die abhängige Anweisung wird solange wiederholt, bis der Wert des do-while-Ausdrucks gleich dem Nullwert (0 oder Leerstring für string-Ausdruck) ist. Die abhängige Anweisung wird also im Unterschied zur while-Anweisung mindestens einmal ausgeführt.

for-Anweisung

Die for-Anweisung hat die allgemeine Form

for (expression1; expression2; expression3)
      statement

und ist äquivalent zu

experession1;
while (expression2) {
      statement;
      expression3;
      }

Zunächst wird der erste Ausdruck bewertet. Anschließend werden, solange der zweite Ausdruck nicht gleich dem Nullwert (0 bzw. Leerstring für string-Ausdruck) ist, die abhängige Anweisung ausgeführt und der dritte Ausdruck bewertet. Der erste for-Ausdruck dient also der Initialisierung, der zweite der Schleifenende-Prüfung, und der dritte typischerweise einer Inkrementierung. Jeder einzelne der drei for-Ausdrücke darf auch fehlen. Die folgende Funktion strwords zerlegt einen als Parameter übergebenen string-Wert in seine einzelnen (durch Blank oder Tabulator) getrennten Worte, speichert diese in einer Liste ab und gibt sie anschließend in umgekehrter Reihenfolge aus:

void strwords(string s)
{
      string strlist[];
      int strcount,i,j;
      char c;
      for ( strcount=0,j=0,i=0 ; c=s[i++] ; ) {
              if (c==' ' || c=='\t') {
                      if (j>0) {
                              strcount++;
                              j=0;
                              }
                      continue;
                      }
              strlist[strcount][j++]=c;
              }
      for ( i=strcount ; i>=0 ; i-- )
              printf("%s\n",strlist[i]);
}

forall-Anweisung

Die forall-Anweisung hat die allgemeine Form

forall (identifier1 of identifier2 where expression)
      statement

Die forall-Anweisung dient der automatischen sequentiellen Abarbeitung der aktuell verfügbaren Elemente eines index-Datentyps. Der erste Identifier muss eine index-Variable referenzieren, über die der Typ des abzuarbeitenden forall-Index spezifiziert wird. Die forall-Anweisung sorgt selbsttätig für die Initialisierung und Inkrementierung dieser Variablen. Ist keine Inkrementierung mehr möglich, weil das letzte Element der index-Liste erreicht ist, dann ist automatisch auch das Ende-Kriterium erreicht und die Programmausführung wird mit der Anweisung, die der forall-Anweisung folgt, fortgesetzt. Die of-Anweisung innerhalb der forall-Anweisung dient der Spezifikation eines dem forall-Index hierarchisch übergeordneten index-Wertes, d.h. der zweite Identifier muss eine index-Variable referenzieren, innerhalb der die Abarbeitung des forall-Index per Definition zulässig ist. Der where-Ausdruck schließlich dient dazu, zu entscheiden, ob die abhängige Anweisung für den aktuellen forall-Index ausgeführt werden soll (Wert des Ausdrucks ungleich dem Nullwert) oder nicht (Wert des Ausdrucks gleich dem Nullwert). Sowohl die of-Anweisung als auch die where-Anweisung können wahlweise weggelassen werden, so dass die kürzeste Form der forall-Anweisung gegeben ist durch

forall (identifier1)
      statement

Die index-Variablen-Typen sind in Anhang B beschrieben. Folgendes Beispiel gibt für alle platzierten Bauteile der aktuell geladenen physikalischen Netzliste eine Liste der Pins aus, die mit dem Netz vcc verbunden sind:

index L_CPART part;
index L_CPIN pin;
forall (part where part.USED) {
      forall (pin of part where pin.NET.NAME=="vcc")
              printf("Part %s, Pin %s ;\n",part.NAME,pin.NAME);

 

2.5.4 Kontrollfluss-Steuerung

Neben den bisher vorgestellten Kontrollstrukturen verfügt die User Language über einige spezielle Kontrollstrukturen, mit denen der Kontrollfluss zusätzlich gesteuert werden kann.

break-Anweisung

Die break-Anweisung hat die allgemeine Form

break;

Die break-Anweisung muss sich in der Abhängigkeit einer repetitiven (while, do-while, for oder forall) oder einer switch-Anweisung befinden (andernfalls Fehlermeldung durch den Compiler). Sie sorgt für den Abbruch der nächstgelegenen repetitiven bzw. switch-Anweisung, d.h. die Ausführung des Programms wird mit der Anweisung fortgesetzt, die der abgebrochenen Anweisung normalerweise folgt.

continue-Anweisung

Die continue-Anweisung hat die allgemeine Form

continue;

Die continue-Anweisung muss sich in der Abhängigkeit einer repetitiven (while, do-while, for oder forall) Anweisung befinden (andernfalls Fehlermeldung durch den Compiler). Sie sorgt dafür, dass die Ausführung des Programms an der Stelle fortgesetzt wird, an der über die Wiederholung der nächstgelegenen repetitiven Anweisung entschieden wird.

Funktionsaufruf und return-Anweisung

Sowohl der Funktionsaufruf als auch die return-Anweisung wurden bereits vorgestellt. Sie seien an dieser Stelle jedoch nochmals aufgeführt, um zu verdeutlichen, dass auch sie den Kontrollfluss entscheidend beeinflussen.

Der Funktionsaufruf ist ein Ausdruck, der einen Sprung zur ersten Anweisung der entsprechenden Funktionsdefinition bewirkt. Die return-Anweisung darf nur innerhalb von Funktionen verwendet werden. Sie sorgt dafür, dass die Ausführung des Programms unmittelbar nach dem Funktionsaufruf der den Sprung in die Funktion veranlasst hat, fortgesetzt wird, d.h. es erfolgt ein Abbruch der Funktionsausführung, und der Kontrollfluss wird wieder an den Aufrufer der Funktion zurückgegeben. Die allgemeine Form der return-Anweisung ist gegeben durch

return;

bzw.

return expression;

Enthält die return-Anweisung keinen Ausdruck, dann ist der Rückgabewert des Funktionsaufrufes undefiniert. Im anderen Fall ergibt sich der Rückgabewert der Funktion aus dem return-Ausdruck, der typ-kompatibel zu dem für die Funktion definierten Datentyp sein muss (ansonsten Fehlermeldung durch den Compiler). Trifft der User Language Compiler auf das Ende eines Funktionsblocks, dann erzeugt er, sofern die letzte Anweisung des Blocks nicht eindeutig als return-Anweisung erkannt werden kann, an dieser Stelle Programm-Code, der einer return-Anweisung (ggf. mit zum Funktionsdatentyp kompatiblem Null-Wert) entspricht. Die Erzeugung eines Nullwertes ist hierbei allerdings nicht für zusammengesetzte Datentypen möglich. D.h., Funktionsdefinitionen der Form

struct structname functionname() { }

provozieren eine Compiler-Fehlermeldung, da der User Language Interpreter beim lesenden Zugriff auf ein Element des Rückgabewertes einer solchen Funktion in jedem Fall eine Speicherzugriffs-Verletzung (Memory Protection Fault) feststellen würde.

Bartels :: Bartels AutoEngineer :: BAE Dokumentation :: User Language Programmierhandbuch :: Sprachbeschreibung :: Kontrollstrukturen

Kontrollstrukturen
© 1985-2017 Oliver Bartels F+E • Aktualisiert: 02. October 2007, 11:22 [UTC]

© 1985-2017 Oliver Bartels F+E Bartels Startseite Kontakt und Impressum

Webentwicklung Baumeister Mediasoft Engineering

Kontrollstrukturen - Deutsche Version Control Structures - English Version