Previous | Contents | Index |
This section describes the following kinds of statements in the C programming language. Except as indicated in this chapter, statements are executed in the sequence in which they appear in a function body:
A label is an identifier used to flag a location in a program as the target of a goto statement or switch statement. A label has the following syntax:
identifier : statement
|
The scope of the label is the containing function body. Variables can have the same name as a label in the function because labels and variables have different name spaces (see Section 2.15).
There are three kinds of labeled statements in C:
The last two statements are discussed in Section 7.5.2 because they can
appear only within a switch statement.
7.2 Compound Statements
A compound statement, or block, allows a sequence of statements to be treated as a single statement. A compound statement begins with a left brace, contains optional declarations followed optionally by statements, and ends with a right brace, as shown in the following example:
{ int x = 5; z = 1; if (y < x) funct(y, z); else funct(x, z); } |
Block declarations are local to the block, and, for the rest of the block, they supersede other declarations of the same name in outer scopes.
A block is entered normally when control flows into it, or when a goto statement transfers control to a label at the beginning of the block itself. Each time the block is entered normally, storage is allocated for auto or register variables. If, on the other hand, a goto statement transfers control to a label inside the block or if the block is the body of a switch statement, these storage allocations do not occur. For more information about storage classes, see Section 2.10.
Function definitions contain compound statements. The compound
statement following the parameter declarations in a function definition
is called the function body.
7.3 Expression Statements
Any valid expression can be used as a statement by following the expression with a semicolon, as shown in the following example:
i++; |
This statement increments the value of the variable i. Note that i++
is a valid C expression that can appear in more complex C statements.
For more information about the C expressions, see Chapter 6.
7.4 Null Statements
A null statement is used to provide a null operation in situations where the grammar of the language requires a statement, but the program requires no work to be done. The null statement consists of a semicolon:
;
|
The null statement is useful with the if, while, do, and for statements. The most common use of this statement is in loop operations in which all the loop activity is performed by the test portion of the loop. For example, the following statement finds the first element of an array that has a value of 0:
for (i=0; array[i] != 0; i++) ; |
In this example, the for statement is executed for its side effects only; the loop body is a null statement. See Section 7.6 for more information about iteration statements.
The null statement is also useful where a label is needed just before a brace that terminates a compound statement. (A label cannot immediately precede the right brace; it must always be attached to a statement.) For example:
if (expression1) { ... goto label_1; /* Terminates this part of the if statement */ ... label_1: ; } else ... |
A selection statement selects among a set of statements depending on
the value of a controlling expression. The selection statements are the
if statement and the switch statement, which are discussed in the
following sections.
7.5.1 The if Statement
The if statement has the following syntax:
if ( expression )
|
elseopt
|
The statement following the control expression is executed if the value of the control expression is true (nonzero). An if statement can be written with an optional else clause that is executed if the control expression is false (0).
Consider the following example:
if (i < 1) funct(i); else { i = x++; funct(i); } |
In this example, if the value of i is less than 1, then the statement funct(i) is executed and the compound statement following the keyword else is not executed. If the value of i is not less than 1, then only the compound statement following the keyword else is executed.
The control expression in a selection statement is usually a logical expression, but it can be any expression of scalar type.
When if statements are nested, an else clause matches the most recent if statement that does not have an else clause, and is in the same block. For example:
if (i < 1) { if (j < 1) funct(j); if (k < 1) /* This if statement is associated with */ funct(k); else /* this else clause. */ funct(j + k); } |
The switch statement executes one or more of a series of cases, based on the value of a controlling expression. The switch statement has the following syntax:
switch ( expression )
|
The usual arithmetic conversions are performed on the control expression, but the result must have an integral type. For more information about data-type conversion, see Section 6.10. The switch statement is typically a compound statement, within which are one or more case statements executed if the control expression matches the case. The syntax for a case label and expression follows:
case constant-expression : statement |
The constant expression must have an integral type. No two case labels can specify the same value. There is no limit on the number of case labels in a switch statement.
Only one statement in the compound statement can have the following label:
default : |
The case and default labels can occur in any order, but it is common practice for the default statement to follow the case statements. Note that execution flows from the selected case into the cases following unless explicit action is taken, such as a break statement.
When the switch statement is executed, the following sequence takes place:
Example 7-1 uses the switch statement to count blanks, tabs, and new-line characters entered from the terminal.
Example 7-1 Using switch to Count Blanks, Tabs, and New Lines |
---|
/* This program counts blanks, tabs, and new lines in text * * entered from the keyboard. */ #include <stdio.h> main() { int number_tabs = 0, number_lines = 0, number_blanks = 0; int ch; while ((ch = getchar()) != EOF) switch (ch) { (1) case '\t': ++number_tabs; (2) break; case '\n': ++number_lines; break; case ' ' : ++number_blanks; break; default:; } printf("Blanks\tTabs\tNewlines\n"); printf("%6d\t%6d\t%6d\n", number_blanks, number_tabs,number_lines); } |
Key to Example 7-1:
Without the break statements, each case would drop through to the next.
If variable declarations appear in the compound statement within a switch statement, initializers on auto or register declarations are ineffective. However, initializations within the statements following a case are effective. Consider the following example:
switch (ch) { int nx = 1; /* Initialization ignored */ printf("%d", n); /* This first printf is not executed */ case 'a' : { int n = 5; /* Proper initialization occurs */ printf("%d", n); break; } case 'b' : { break; } default : { break; } } |
In this example, if ch :=,= 'a', then the
program prints the value 5. If the variable equals any other letter,
the program prints nothing because the initialization occurs outside of
the case label, and statements outside of
the case label are ineffective.
7.6 Iteration Statements
An iteration statement, or loop, repeatedly executes a statement, known as the loop body, until the controlling expression is false (0). The control expression must have a scalar type.
The while statement evaluates the control expression before executing the loop body (see Section 7.6.1).
The do statement evaluates the control expression after executing the loop body; at least one execution of the loop body is guaranteed (see Section 7.6.2).
The for statement executes the loop body
based on the evaluation of the second of three expressions (see
Section 7.6.3).
7.6.1 The while Statement
The while statement evaluates a control expression before each execution of the loop body. If the control expression is true (nonzero), the loop body is executed. If the control expression is false (0), the while statement terminates. The while statement has the following syntax:
while ( expression )
|
Consider the following while statement:
n = 0; while (n < 10) { a[n] = n; n++; } |
This statement tests the value of n; if
n is less than 10, it assigns n to the nth element of the array
a and then increments n. The control expression (in parentheses) is
then evaluated; if true (nonzero), the loop body is executed again; if
false (0), the while statement
terminates. If the statement n++ were
missing from the loop body, this while
statement would never terminate. If the statement n =
0 were replaced by the statement n =
10, the control expression is initially false (0), and the
loop body is never executed.
7.6.2 The do Statement
The do statement evaluates the control expression after each execution of the loop body. The do statement has the following syntax:
do
|
The loop body is executed at least once. The control expression is
evaluated after each execution of the loop body. If the control
expression is true (nonzero), the statement is executed again. If the
control expression is false (0), the do
statement terminates.
7.6.3 The for Statement
The for statement evaluates three expressions and executes the loop body until the second controlling expression evaluates to false (0). The for statement is useful for executing a loop body a specified number of times. The for statement has the following syntax:
for ( expression-1opt ;
|
The for statement is equivalent to the following code:
expression-1; |
while ( expression-2 )
|
The for statement executes the loop body zero or more times. Semicolons (;) are used to separate the control expressions. A for statement executes the following steps:
Any of the three expressions in a for loop can be omitted:
for (i = 0; ;i++) statement; |
n = 1; for ( ; n < 10; n++) func(n); |
Jump statements cause an unconditional jump to another statement elsewhere in the code. They are used primarily to interrupt switch statements and loops.
The jump statements are the goto
statement, the continue statement, the
break statement, and the return statement, which are discussed in the
following sections.
7.7.1 The goto Statement
The goto statement unconditionally transfers program control to a labeled statement, where the label identifier is in the scope of the function containing the goto statement. The labeled statement is the next statement executed. The goto statement has the following syntax:
goto identifier; |
Care must be taken when branching into a block by using the goto statement, because storage is allocated for automatic variables declared within a block when the block is activated. When a goto statement branches into a block, automatic variables declared in the block are not initialized.
Previous | Next | Contents | Index |