Flow Commands

Flow Commands

Loops and if tests. Flow control is styled to replicate the common syntax used in C. Because of this, providing an in-depth explanation here is unnecessary since lots of people have already written far clearer and more in-depth documents. A good Google should find them.

do

Syntax:

do { commands } while { condition }

The do-while loop is cousin of the 'for' loop, except that there is no control variable. The termination of the loop depends on the condition which is tested at the end of every execution of the commands. If 'true', the commands are executed again, and condition re-tested afterwards. If 'false' the loop ends.

For example:

int i = 1;
do
{
	i = i * 2;
	printf("i = %d\n", i);
} while (i < 100)

will print out the following:

i = 2
i = 4
i = 8
i = 16
i = 32
i = 64
i = 128

Note that the final value of i inside the loop is '128' (greater than 100) since the condition is only tested at the end of the execution of the commands. The while loop works in the same way, save that the condition is tested at the beginning of the loop, before commands are executed, rather than at the end.

for

Syntax:

for ( startvalue ; condition ; increment ) { commands }

Three separate components make up a 'for' loop. startvalue defines both the control variable (i.e. the variable that changes on each loop iteration) and optionally its starting value, the condition is tested on each loop iteration to see whether or not to continue with the loop, and finally the increment is an expression to modify the control variable after each iteration, setting it to a new value. If multiple commands are to make up the body of the loop (executed on each iteration) then they should be enclosed in curly brackets (as written in the syntax above). If only a single command is executed on each iteration, the curly brackets may be omitted.

Some examples:

for (int i=1; i<=10; i = i + 1) printf("%i\n", i);

Loop over and print all integers between 1 and 10. A local variable i is declared and initialised all in one go in the startvalue part of the loop. The 'long' way of incrementing the integer variable (i = i + 1) is typically not used in C/C++, most people preferring to take advantage of the C's useful postfix and prefix operators, as in the next example).

for (n = 100; n>0; --n) printf("Counting down... %i\n", n);

Here, an existing variable n is decreased from 100 to 1, printing out all numbers along the way. Note the usage of the double-minus '--' operator (the prefix decrease operator) which decreases its associated variable, in this case n. For integers, to decrease means to reduce the value by 1. For other types the meaning may vary - for instance, with reference types the '--' operator means 'previous item in the list', since all such objects in Aten (e.g. atoms) are stored in lists containing many objects of the same type. This makes iterating over, say, all atoms in a given model pretty easy...

for (atom a = aten.model.atoms; a; ++a) printf("Atom id %i is element %s.\n", a.id, a.symbol);

In this example the variable a is declared and initialised to be a reference to the first atom in the current model. The condition part simply consists of the expression 'a', which effectively tests the reference address currently stored in a. Since any positive number equates to 'true' (see below for the 'if' test) the loop will continue until a contains no reference. Since most all reference objects in Aten are stored internally in linked lists, the prefix increment operator ('++') changes the value of the variable to be the reference of the next item in the list, or 0 if there are no more items. In this way, the whole list of atoms can be traversed and neatly ended once the final item in the list has passed.

if

Syntax:

if ( condition ) { commands }
if ( condition ) { commands... } else { commands }

The 'if' statement permits sections of code to be executed based on the assessment of logical comparison of values. If the supplied condition evaluates to be 'true' then the following commands are executed, otherwise nothing happens. In the second form of the command, if the condition evaluates to be 'false' then the second set of commands are executed instead. If multiple commands are to be executed then they should be enclosed in curly brackets (as written in the syntax above). If only a single command is to be executed the curly brackets may be omitted.

Typically, comparisons are made between two variables, for example 'if ( var1 > var2 ) ... ' checks for var1 being greater in value than var2, executing the following commands if this turns out to be true. The comparison operator may be any one of the following symbols:

Table 6.23. Test Operators

OperatorMeaning
==Equal to
!=Not equal to
<>Not equal to
>Greater than
<Less than
>=Greater than or qual to
<=Less than or qual to

In truth, the condition part may be any expression, command, or amalgam of both, provided the end result of executing it is a single value. The type of the final result doesn't even matter, since conversion to a boolean is guaranteed. Deep down in the logic of Aten, integers are at the heart of it all, with zero or any negative number being 'false', and any positive number meaning 'true'.

For example:

int i = 10;
if (i > 5) printf("Hooray!\n");

in this case 'Hooray!' will be printed, because i is greater than 5.

int i = 10, j = 20;
if (i > j) printf("Hooray!\n");

but in this case 'Hooray!' will not be printed, because i is not greater than j.

int i = 10, j = 20;
if (i > j) printf("Hooray!\n"); else { printf("Too small.\n"); i = j; }

Here, the test fails for the same reason, but since an 'else' part was provided we still execute some commands (printing 'Too small.' and setting the variable i equal to j).

			if (i) printf("Snoopy.\n");

since any positive number is 'true', we can simply test the value of a variable.

atom a = newatom("H");
if (a) printf("New atom.\n");

In a similar way, a reference variable has a positive integer value at its heart, and so can also be tested in this way.

atom a = newatom("H");
double alpha = 100.0;
if ( (a) && (alpha < 50.0) ) printf("Alpha and atom are OK.\n"); else printf("No good!\n");

Two or more consecutive conditions can be tested in order to determine 'truth', in this case using the 'and' operator '&&'. Here, the value of the reference variable a and the value of alpha are both checked, and the text 'Alpha and atom are OK.' is only printed if both turn out to be 'true'.

if (time == 0) printf("There is no time.");
else if (time > 5) printf("There is more than enough time.");
else printf("There is only a little time.");

Multiple if tests can also be nested to create a sequence of tests. As soon as a condition is encountered that equates to 'true' the accompanying commands are executed and any subsequent 'else'd tests or commands are ignored.

return

Syntax:

return(); 
return(value); 
 value;

Used in (user-defined) functions, and returns control immediately back to the calling function. In the case of a 'void' function, no return value must be specified. Similarly, for functions returning a value a valid value of that type must be given.

while

Syntax:

while ( condition ) { commands }

The while loop is another cousin of the 'for' loop, and as with the do-while loop there is no control variable. The termination of the loop depends on the condition which is tested at the beginning of the loop, before execution of the commands. If 'true', the commands are executed, but if 'false' the loop ends without executing the commands (and meaning that it is possible that the commands are never executed).

For example:

int i = 1024;
while (i > 100)
{
	i = i / 2;
	printf("i = %d\n", i);
}

will print out the following:

i = 512
i = 256
i = 128
i = 64