case label must
always be terminated by a break
statement.
switch statement must always
contain a default
branch which handles unexpected cases.
goto.
for,
while or do-while) should depend on the specific use of
the loop.
unsigned
for variables which cannot reasonably have negative values.
continue.
break
to exit a loop if this avoids the use of flags.
if(test) or if(!test) when test
is a pointer.
Each loop construct has a specific usage. A for loop is used only when
the loop variable is increased by a constant amount for each iteration and when
the termination of the loop is determined by a constant expression. In other cases,
while or do-while should be used. When the terminating
condition can be evaluated at the beginning of the loop, while should
be used; do-while
is used when the terminating condition is best evaluated at the end of the loop.
Goto breaks the control flow and can lead to code that is difficult
to comprehend. In addition, there are limitations for when goto
can be used. For example, it is not permitted to jump past a statement that initializes
a local object having a destructor.
Variables representing size or length are typical candidates for unsigned
declarations. By following this recommendation some unpleasant errors can be avoided.
It is best to use inclusive lower and exclusive upper limits. Instead of saying
that x is in the interval x>=23 and x<=42,
use the limits x>=23 and x<43. The following important
claims then apply:
By being consistent in this regard, many difficult errors will be avoided.
If the code which follows a case label is not terminated by break,
the execution continues after the next case
label. This means that poorly tested code can be erroneous and still seem to work.
continue can be used to exit from loops. However, code may be more
comprehensible by using an else
clause instead.
C++ has a very loose and, simultaneously, very free way of determining if an expression is true or false. If an expression is evaluated as 0, it is false; otherwise, it is considered to be true.
We do not recommend logical tests such as "if(pointer)"
if "pointer
" is a variable of pointer-type. The only reason is readablity; many programmers
find it difficult to read such code.
Consider the scope within which an iteration variable is visible. A variable that
is declared within a `for' statement is currently only visible in the
nearest enclosing block. The standardization committee for C++ is however discussing
a language modification regarding this point. No decision has yet been made. Still,
this problem is avoided if the control structure is encapsulated in a compound statement.
case labels
are followed by the same block of code, only one break statement is
needed. Also, other statements than break may be used to exit a switch
statement, such as return.
goto
may be permitted. Every such usage must be carefully motivated.
for( unsigned int i = 3; i >= 0; --i )
{
// This
loop will never terminate, since i cycles through:
// 3, 2, 1, 0, 4294967295,
4294967294, etc ... on a SparcStation
// Note that this example does not
follow the rules: i >= 0
// in the for statement. See next example !
}
for'
loop
for ( int index = 0; index < 10; index++ )
{
cout << index;
}
int index = 3; // ERROR, THIS IS AN ILLEGAL RE-DECLARATION OF index
// BECAUSE index IS DECLARED IN BLOCK-SCOPE.
switch/case statement
switch ( tag )
{
case A:
{
// Do something
// Next statement is a call to foo() inside next case
}
case B:
{
foo();
// Do something else
break; // Now we leave the switch-statement
}
default:
{
// If no match in above cases, this is executed
exit( 1 );
}
}
int a[10];
int ten = 10;
int nine = 9;
// Good way to do it:
for( int i = 0; i < ten; i++ ) // Loop runs 10-0=10 times
{
a[i] = 0;
}
// Bad way to do it:
for( int j = 0; j <= nine; j++ ) // Loop runs 10 times,
but 9-0=9 !!!
{
a[j] = 0;
}
do // This way:
{
if ( Something )
{
// Do something
break;
}
} while( someCondition );
int endFlag = 0; // Is better than this:
do
{
if ( /* Something */ )
{
// Do something
endFlag = 1;
}
} while( someCondition && !endFlag );
else' clause,
continue is avoided and the code can be comprehended.
while( /* Something */ ) // This way is more clear
{
if( /* Something */ )
{
// Do something
}
else
{
// Do something else
}
}
while( /* Something */ ) // Than using continue
{
if( /* Something */ )
{
// Do something
continue; // No !
}
// Do something else
}