1.2.3 Statement Flow Control


Origin C supports all ANSI C flow control statements including the if, if-else, switch, for, while, do-while, goto, break, and continue statements. In addition, Origin C supports the C# foreach statement for looping through a collection of objects.

The if Statement

The if statement tests a condition and executes a block when the test is true. The if-else statement executes an alternative block when the test is false.

Examples using different input types:

bool bb = true;    // Boolean
if( bb )
{
    out_str("bb is true");
}

int nn = 5;
if( nn )           // Integer: 0 = false, non-zero = true
{
    out_str("nn not 0");
}

double* pData = NULL;
if( NULL == pData ) // Pointer check
{
    out_str("Pointer pData is NULL");
}

An if-else block:

bool bRet = true;
if( bRet )
{
    out_str("Valid input");      // when bRet is true
}
else
{
    out_str("INVALID input");    // when bRet is false
}

Braces are optional if the block has only one statement:

if( bRet )
    out_str("Valid input");
else
    out_str("INVALID input");

An else if ladder (common pattern):

int score = 86;
if( score >= 90 )
    out_str("Grade: A");
else if( score >= 80 )
    out_str("Grade: B");
else if( score >= 70 )
    out_str("Grade: C");
else
    out_str("Grade: D/F");

The switch Statement

Use switch to execute different blocks for mutually exclusive choices. The break statement exits the switch block (a break after default is optional but harmless).

// Using an enum makes intent clearer
enum DataType { TYPE_INT = 1, TYPE_FLOAT = 2, TYPE_STRING = 3, TYPE_OTHER = 4 };

int nType = TYPE_FLOAT;
switch( nType ) // integer value as condition
{
case TYPE_INT:
case TYPE_FLOAT:
    out_str("Numeric type");
    break;

case TYPE_STRING:
    out_str("String type");
    // no break here, fall through to TYPE_OTHER

case TYPE_OTHER:
    out_str("Other type");
    break;

default:
    out_str("Unrecognized type");
    break; // optional
}

The for Statement

The for statement runs a fixed number of times or steps through an array by index.

char str[] = "This is a string";
int n = strlen(str);
for( int index = 0; index < n; index++ )
{
    printf("char at %2d is %c\n", index, str[index]);
}

Iterating over a vector by index and by element:

vector<double> v = {1.2, 3.4, 5.6};

// Index-based
for( int i = 0; i < v.GetSize(); i++ )
    printf("v[%d] = %g\n", i, v[i]);

// Element-based using foreach over the collection
foreach(double val in v)
    printf("val = %g\n", val);

The while Statement

while and do-while execute a block until a condition is met. while tests at the beginning; do-while tests at the end.

int count = 0;
while( count < 10 )
{
    out_int("count = ", count);
    count++;
}

A simple menu loop with do-while (executes at least once):

int choice;
do
{
    out_str("1) Import  2) Analyze  3) Exit");
    choice = 3; // substitute a real input mechanism if needed

    if( 1 == choice )
        out_str("Importing...");
    else if( 2 == choice )
        out_str("Analyzing...");
}
while( choice != 3 ); // exit on 3

Jump Statements

Jump statements unconditionally transfer control within a function: break, continue, and goto.

break

The break statement exits the nearest enclosing loop or switch immediately.

for( int index = 0; index < 10; index++ )
{
    if( pow(index, 2) > 10 )
        break; // terminate for loop

    out_int("index = ", index);
}

continue

The continue statement skips the rest of the current loop iteration and proceeds with the next iteration.

printf("The odd numbers from 1 to 10 are:\n");
for( int index = 1; index <= 10; index++ )
{
    if( (index % 2) == 0 )       // use % (modulus) to test even/odd
        continue;                // skip even numbers

    printf("%d\n", index);
}

Another continue use: skip blanks when counting letters.

const char* s = "A B  C";
int letters = 0;
for( int i = 0; s[i]; i++ )
{
    if( ' ' == s[i] )
        continue;
    letters++;
}
out_int("letters = ", letters); // 3

goto

The goto statement jumps to a labeled statement within the same function. Use sparingly; structured control flow is usually clearer.

out_str("Begin");
goto Mark1;

out_str("Skipped statement");

Mark1:
out_str("First statement after Mark1");

The foreach Statement

Use foreach to loop through a collection. The example below iterates all pages in the project and prints name and type.

foreach(PageBase pg in Project.Pages)
{
    printf("%s is of type %d\n", pg.GetName(), pg.GetType());
}

Refer to the Collections section for a list of all collection-based classes in Origin C.