../pvss.htm menu.gif basics.gif

Control structures in CTRL

An instruction within a control structure can be made up of one individual command or several commands. In the latter case the commands must be grouped together in curly brackets.

if-else

The if instruction is used to make execution of commands dependent on the value of a test expression.

Syntax

if (<Test expression>)
<instruction1>

else
<instruction2>

 

Instruction1 is only executed if the test expression is true (returns a value that does not equal zero). Otherwise the instruction is skipped and execution continues with instruction2 in the optional else section. If there is no else section, the command that follows instruction1 is executed if the test expression is false.

IconExample

 

main()
{
int rc;
float x, y, z;
dpGet ("Valve17.adjustment:_original.._value", x);
if (x > 0) // depends on original value x
{
y = 1; // y and z are set
z = 2;
}
else
if(x < 0)
 {
 y = -1;
 z = 0;
 }
else
 {
 y = 0;
 z = -1;
 }
 DebugN(x, y, z);
}

switch

The switch instruction enables a program to branch according to the value of a test expression.

Syntax

switch(<Test expression>)
{
case <expression1>
: <instruction1>
case <expression2>
: <instruction2>....]
[default: Default instruction]
}

 

The commands that are executed are all those contained in that case section whose relational expression has the same value as the test expression. If none of the relational expressions in the switch construct meet this condition, then only the instruction in the optional "default" section is executed. If there is no default part, execution continues with the instruction following the switch construct. In order to prevent executing all the other instructions in the switch construct after performing an instruction in a case section, a break statement must be used to escape it.

Icon Caution

Note that only expressions whose value is known at the parse time (constant expressions) are allowed. Such expressions are:
1. Constants , for example, 4 or "example"
2. Expressions  which lead to a constant , for example, 4 * 2 or  "example1" + "example2"
3. Constant variables that were defined in the concerned script , for example,  const int i =4; or const string f = "example";

NOT ALLOWED are expressions whose value can be determined first at runtime. Such expressions are:
1. Functions (example())
2. Not constant variables (int i;)
3. If conditions  (i > 0 ? 1 : 2);

IconExample

main()
{
   float y =2;
   string s = "ab";
   const string f = "example1"; //constant variable
   const string c = "example2";
   string fo = "example1";
   switch(y)
   {
      case 1.0 + 1.0 : //expression that leads to a
           //constant

      DebugN("case 1 = 2");
   break;
     case 4.2 + 5.3 :  //expression that leads to a
          //constant

     DebugN("case 2= 9");
  break;
  default:
     DebugN("DEFAULT OF FLOAT");
}
switch(s)
{
    case "a" + "b" :  //expression that leads to a
          //constant

    DebugN("a+b of a String");
  break;
   case "a":         //expression that leads to a
          //constant

   DebugN("a of a String");
  break;
  default:
   DebugN("DEFAULT OF A STRING");
}
switch(fo)
{
   case f :
   DebugN("Constant F"); //Constant variable
  break;
   case c :
   DebugN("Constant C"); //Constant variable
 break;
 default:
   DebugN("DEFAULT OF THE CONSTANT");
}
}

 

while

The while instruction is used for repeated execution of commands according to the value of a test expression.

Syntax

while (<Test expression>)
<instructionW>

 

InstructionW is only executed if the test expression is true (returns a value that does not equal zero). As soon as the instruction has been executed the test expression is evaluated again. If it is still true, instructionW is executed again. If the test expression is false, instructionW is skipped, and execution continues with the next command.

IconExample

The following script calculates the factorial of 10 (10! = 1*2*3 ...*10).

 

main()
{
int i,n,nfact;
n = 10;
nfact = 1;
i = 1;
while (i<=n) // as long as i <= 10
{
nfact*=i; // multiplied by i
i++; // and then i is incremented by one
}
DebugN(nfact); // Result 10! = 3628 800
}

for

The for instruction creates program loops that are executed as long as the test expression is true.

Syntax

for ([<expression1>]; [<Test expression>]; [<expression3>])
<instructionF>

 

Expression1 is evaluated before the loop is first executed. Normally this is the initialization of a counter variable. InstructionF is only executed if the test expression is true (returns a value that does not equal zero). As soon as the instruction has been executed expression3 and the test expression are evaluated. If the test expression is still true, instructionF is executed again. If the test expression is false, instructionF is skipped, and execution continues with the next command. Each of the three expressions in the condition statement is optional. If there is no test expression then the condition is always considered true. Thus the first of the following examples sets up an endless loop:

IconExample of an endless loop

 

main()
{
int i,n,nfact;
n = 10;
nfact = 1;
i = 1;
for (i=1;;i++) // leads to an endless loop!!
nfact *= i;
DebugN(nfact); // no result is output because of the endless loop

}

IconExample 2

 

main()
{
int i,n,nfact;
n = 10;
nfact = 1;
i = 1;
for(i=1; i<=n; i++)
 nfact *= i;
DebugN(nfakc); // Result 10! = 3 628 800

}

do-while

The do instruction is used for repeated execution of commands according to the truth value of a test expression, although the commands are always executed at least once.

Syntax

do
<instructionD>
while (<Test expression>)

 

As soon as instructionD has been executed the test expression is evaluated again. If it is true (returns a non-zero value) instructionD is executed again. If the test expression is false, execution continues with the next command.

IconExample

 

main()
{
int i,n,nfact;
n = 10;
nfact = 1;
i = 0;
do
{
++i;
nfact *= i;
}
while(i<=n);
DebugN(nfact);
}

break

The break command is used for exiting switch instructions, and for, while and do loops prematurely.

Syntax

break;

 

After a break instruction, execution continues with that command that follows the innermost enclosing do, while or for loop, or switch instruction.

continue

The continue command is used for performing the next iteration of for, while and do loops prematurely.

Syntax

    continue;

After a continue instruction, execution continues at the end of the innermost enclosing do, while or for loop. At the same time all expressions in the loop condition are evaluated again.

IconExample

 

for (i=0; i < len; i++)
{
if (field[i] == 0)
continue;
field[i] = 1 / field[i];
}

try - catch/finally - throw

The try-catch statement provides catching of exceptions, which either are thrown explicitly by throw() or were triggered by script errors (e.g. not declared variable, index out of range, division by zero, etc.).
 

Syntax

try {

    statements;

    throw(errClass e)      // optionally

}
catch            

{                                           

    statements;                 

}
finally         
{                                 

    statements;

}

 

The code/statements, which are "tried" and eventually are thrown a exception, are defined in a try-block. If an exception occurs during the execution of these statements, a catch-block or a finally-block will be executed.

After a try-block must follow a catch-block, a finally-block or both together in a catch-finally order.

The catch-block catches the exception and deletes it. If additionally a finally-block follows, so this will be executed after the catch-block. If not, so the not already executes statements in the try-block will be treated.

The finally-block will be executed independent of the case whether an exception was thrown or a catch-block is given. The finally-block is then useful when in each case a specific code should be executed (e.g. variable reset), even if the exception cannot be treated at this point.

The throw(errClass e) function throws an exception ('e'). An exception is always of the type errClass.

Exception in the finally-/catch-block

If an exception occurs in the finally-block, the treatment will be canceled and the block continues the "roll up" till the next try-catch/-finally block is found. An exception will be always replaced by the newest/current exception.

If an exception occurs in the catch-block, the treatment will be canceled, but an eventually existing finally-block will be executed before "rolling up" the block in order to find a new try-catch/-finally block. An exception will be always replaced by the newest/actual exception.

If during the "roll up" no other try-catch/-finally block is found, the thread will be exited and an error message will be returned ("uncaught exception ...").

IconExample

 

main()

{

  try

  {

    DebugN("main: try");

    throw(makeError("", PRIO_SEVERE, ERR_PARAM, 54, "In main:try"));

    foo();

    DebugN("main: try end");

  }

  catch

  {

    DebugN("main: catch");

    DebugN(getLastException());

    // throw(makeError("", PRIO_SEVERE, ERR_PARAM, 54, "In main: catch"));   

    DebugN("main: catch end");

  }

  finally

  {

    DebugN("main: finally");

    // throw(makeError("", PRIO_SEVERE, ERR_PARAM, 54, "In main: finally"));   

    DebugN("main: finally end");

  }

  DebugN("main: end");

}

foo()

{

  try

  {

    DebugN("foo: try");

    throw(makeError("", PRIO_SEVERE, ERR_PARAM, 54, "In foo:try"));

    DebugN("foo: try end");

  }

  finally

  {

    DebugN("foo: finally");

    // throw(makeError("", PRIO_SEVERE, ERR_PARAM, 54, "In foo:finally"));

    DebugN("foo: finally end");

  }

  DebugN("foo: end");

}

Top Of Page

 

V 3.11 SP1

Copyright ETM professional control GmbH 2013 All Rights Reserved