The goto statement is an unconditional control flow change. To be able to write any needed program, a conditional control flow statement is needed. This conditional control flow statement, called the "if" statement, has been around in many forms. The simplest and most common is as it is in the 'C' language and many other languages. It takes the form illustrated by the following program fragment consisting of one simple if statement:
if (expression) statement_1;
In words, what will happen is that statement_1 will be executed only if 'expression' is true. In 'C', an expression is true if its value is non zero, and it is false if its value is zero.
For subsequent control flow statements, we will abbreviate all expressions by 'e', or by 'e' followed by a number (e.g. e1, e2), and all statements by 's', or 's' followed by a number (e.g. s1, s2).
Thus the above becomes:
if (e) s;
The white space after the "if" and before the 's' are not needed. Usually the statement, 's', within the "if" statement is indented and shown on the next line:
if (e) s;
When 'e' and 's' are very long it becomes helpful to put 's' on the next line, as above, so that the text fits within the horizontal limits of the screen or printed page. Even when 's' and or 'e' are not long, indenting makes the program clearer by making the conditional part stand out. When the control flow gets more complicated by having control flow statements within control flow statements, indenting becomes essential for the human reader of the program. The compiler, of course, couldn't care less.
The flow chart for the "if" statement is:
| v / \ < e >-------\ \ / T | | v | F +---+ v | s | | +---+ | | +-<-------/ | v
Note the diamond shape with the conditional expression inside and the two possible paths out.
When more than one statement is to be executed conditionally on 'e', then a block statement (i.e. a list of statements enclosed within curly braces) is used. It is strongly advised that the ending or right curly brace line up with the 'i' in the "if" keyword so that the end of the block is easy to see:
if (e) { s_1; s_2; ... s_n; }
The flow chart is essentially the same, except that there are multiple statements in the path taken when 'e' is true. If the curly braces are left off, even though you indent, only s_1 will be executed if 'e' is true, and 's_2' through 's_n' will be executed always. This is a common mistake made even by advanced programmers.
Frequently, one wants to execute one list of statements if a condition is true and a different list of statements if the conditions is false. This could be done by using 'goto' statements:
if (e) goto label1; /* --- 'e' is false --- */ s2; /* may be one or more statements */ goto label2; /* --- 'e' is true --- */ label1: s1; /* may be one or more statements */ label2:
This works well enough, but it begins to be spaghetti-like. The solution is the optional 'else' clause for the 'if' statement. Using the 'else' clause, the above is written in the much simpler form:,/p>
if (e) s1; else s2;
Note the elimination of the goto's and the labels in the source code. Since most computer's machine language instructions are restricted to conditional jumps (or conditional goto's), that is if's where the statement clause can only be a goto - in source form:
if (e) goto label;
Thus, the savings is only at the source language level, but it is a significant one in time to write the program, in ease of understanding and in ease of changing the program - if that becomes necessary.
It is usually better written programming style to show the 'if' with the else's statement clause indented as follows:
if (e) s1; else s2;
unless, 'e', 's1', and 's2' are very short.
The flow chart for the 'if' with 'else' clause is:
| v / \ < e >-------\ \ / T | F | v v +----+ +----+ | s1 | | s2 | +----+ +----+ | | | +-<-------/ | v
In 'C' the statements 's1' and 's2' can be any 'C' statement, including another 'if'. When there are nested 'if' statements it may become unclear to which 'if' a given 'else' belongs. For example:
if (e1) if (e2) s1; else s2;
From the indenting, the programmer's intention was probably to have the 'else' clause apply to the first 'if'. But since the rule is that the 'else' clause belongs to the nearest previous 'if' without an 'else' the compiler would interpret the above as:
if (e1) if (e2) s1; else s2;
If the former was really wanted then curly braces would have to be used to override the normal syntax:
if (e1) { if (e2) s1; } else s2;
If, as frequently happens, a series of 'if's followed by 'else if's is needed. If the usual practice of indenting was used we would get the following:
if (e1) s1; else if (e2) s2; else if (e3) s3; else if (e4) s4; else s5;
As one can see, pretty soon, the indenting gets to be so much, that one has passed the right edge of the screen or page. Because of this, the usual practice is to indent the above as follows:
if (e1) s1; else if (e2) s2; else if (e3) s3; else if (e4) s4; else s5;
As you can see there is no loss of clarity in this form.