Structured and Unstructured Programming
Introduction
Unstructured programming is historically the oldest programming paradigm and capable of creating Turing-complete algorithms (see also Turing machine).
There are high-level and low-level programming languages that use Unstructured Programming. Some of the languages commonly classified as “unstructured” include JOSS, FOCAL, TELCOMP, Assembly languages, MS-DOS command files, and early versions of Fortran, BASIC, COBOL, and MUMPS.
A program written in an unstructured way uses jump instructions (i.e. the goto
instruction) to labels or to instruction addresses. The lines of this program are usually numbered (as in BASIC) or may have “labels” which allows the flow of execution to branch to any line of the program. This is in contrast to Structured Programming which uses block constructs (i.e. if/then/else
statements) and loops (i.e. while
, for
, …).
This may not be so obvious, but you have already done “Structured Programming” when learning Algorithmics! Take for example the following construct in C:
if (/* Condition */)
{
/* Block */
}
/* next statements... */
When condition is false, the program execution skips the block (delimited by curly braces) of the if
statement and executes the next statements. In other words, there is a jump/branch to the next block of code! In unstructured programming, it is the programmer (you) who explicitly introduces jump statements into the program. Thus, the previous example in an unstructured format becomes:
if ( /* NOT Condition */) goto FI;
/* Block */
FI:
/* remaining od the program ... */
Here, a goto
statement with the associated label (i.e. the FI
text) is introduced into the program to accomplish the same task as before. Note that:
- the condition of the
if
statement is flipped here (with the NOT keyword) to achieve the same behavior as in the structured format (i.e. take the branch if Condition is false), - and, the removal of the curly braces which are no longer required.
A goto
statement in C programming allows you to unconditionally jump from the goto
instruction to a labeled statement in the same function. The syntax for a goto
statement in C looks like:
goto label;
..
.
label: instruction;
Here, label
can be any alphanumeric string (except C keywords), and can be defined anywhere in a C function (i.e. above or below a goto
statement).
Examples of “structured” and “unstructured” codes
if/then/else statements
Structed Code | Unstructured Code |
---|---|
if( /* Condition */ )
{
/* Block 1 */
}
else
{
/* Block 2 */
}
/* next statements... */
|
if( /* NOT Condition */ ) goto ESLE;
/* Block 1 */
goto FI;
ESLE:
/* Block 2 */
FI:
/* next statements... */
|
Here, two goto
statements are introduced: the first goto
(i.e. goto ESLE
) allows to branch to the else
block if the condition is false. In case the condition is true, Block 1 is executed and the second goto
at the end of this block (i.e. goto FI
) allows to jump to the “next statements” of the program and not execute Block 2.
“while” and “for” loops
Converting a while
loop to “unstructured code” is very similar to converting an if/then
block. Indeed, a quick comparison between the “unstructured code” below and that of the if/then
block introduced earlier in this page shows that, in addition to the flipping of the condition expression (i.e. NOT Condition), we substitute the while
statement with a if
statement and insert a second goto
at the end of the loop block, just before the exit NEXT:
label. This allows us to loop back and test the condition expression again for a new iteration.
Structed Code | Unstructured Code |
---|---|
while( /* Condition */ )
{
/* Block */
}
/* next statements... */
|
ELIHW:
if( /* NOT Condition */ ) goto NEXT;
/* Block */
goto ELIHW;
NEXT:
/* next statements... */
|
To convert a for
loop into unstructured code, note that this loop is conceptually equivalent to a while
loop. Indeed, it is possible/easy to rewrite any for
loop in the C language into a while
loop (see the example below).
for loop | while loop | |
---|---|---|
for( i = 0; i < N; i++ )
{
/* Block */
}
/* next statements... */
|
⇔ |
i = 0;
while( i < N )
{
/* Block */
i++;
}
/* next statements... */
|
“do..while” loops
Enfin, comme pour la boucle while
vue plus haut, la transformation vers un code non structuré de la boucle do..while
requiert le remplacement du mot clé while
par le mot clé if
. Notons toutefois, que la condition de la boucle reste inchangée (c.-à-d. non inversée). Notons aussi qu’un seul goto
est introduit pour retourner au début de la boucle do / while
.
Finally, as for the while
loop seen above, transforming the do..while
loop into unstructured code requires replacing the while
statement with a if
statement. Note, however, that the loop condition remains unchanged (i.e. not inverted). Note also that a single goto
is introduced here (to return to the start of the do..while
loop).
Structed Code | Unstructured Code |
---|---|
do
{
/* Block */
}
while( /* Condition */ );
/* next statements... */
|
OD:
/* Block */
if( /* Condition */ ) goto OD;
/* next statements... */
|
switch/case statements
A naive approach to converting a switch/case
block of code into an unstructured program would be to rewrite this block as a series of if/then/else
statements and subsequently convert these instructions as described earlier. Another, more efficient approach would use the following steps:
-
Convert each
case i
statement into a unique label (ex:case 5
will becomeESAC5
). -
allocate an array before the
switch
statement with enough space to hold all the addresses of thelabels
produced in step 1 (i.e. labels ESAC0, ESAC1, …). -
add a label at the end of the
switch/case
block (ex:KAERB:
) and convert eachbreak
statement of theswitch
block to agoto
statement to this new label (ex:goto KAERB;
) in order to jump to the end of the block. -
Finally, the
switch
statement is converted with a couple of instructions: We need first to evaluate theexpression
of theswitch
statement and then according to this value we retrieve the address of the label stored in the allocated array from step 2. We then make the appropriate jump with agoto
instruction again (see below).
Structed Code | Unstructured Code |
---|---|
switch( /* Expression */ )
{
case 0: /* Block 0 */
break;
case 1: /* Block 1 */
break;
...
case N: /* Block N */
break;
default: /* Default */
}
/* next statements... */
|
void *SwitchTab[] = { &&ESAC0, &&ESAC1, ..., &&ESACN, &&TLUAFED };
goto *SwitchTab[ /* Expression */ ];
ESAC0: /* Block 0 */
goto KAERB;
ESAC1: /* Block 1 */
goto KAERB;
...
ESACN: /* Block N */
goto KAERB;
TLUAFED: /* Default */
KAERB:
/* next statements... */
|
NOTE: The steps described above assumes the use of the GCC compiler which provides a feature called “labels as values” - Other C compilers might use other methods for the conversion.