|Access||Adobe photoshop||Algoritmi||Autocad||Baze de date||C||C sharp|
|Calculatoare||Corel draw||Dot net||Excel||Fox pro||Frontpage||Hardware|
|Php||Power point||Retele calculatoare||Sql||Tutorials||Webdesign||Windows|
|Asp||Autocad||C||Dot net||Excel||Fox pro||Html||Java|
statement has two forms:
In the first form, if (and only if) the expression is non-zero, the statement is
executed. If the expression
is zero, the statement
is ignored. Remember that the statement
can be compound; that is the way to put several statements under the control of
The second form is like the first except that if the statement shown as statement1 is selected then statement2 will not be, and vice versa.
Either form is considered to be a single statement in the syntax of C, so the following is completely legal.if(expression)
if statement. Since
that is legally a statement, the first
can be considered to read
and is therefore itself properly formed. The argument can be extended as far as you like, but it's a bad habit to get into. It is better style to make the statement compound even if it isn't necessary. That makes it a lot easier to add extra statements if they are needed and generally improves readability.
The form involving
works the same way, so we can also write this.
As Chapter 1 has said already, this is now ambiguous. It is not clear,
except as indicated by the indentation, which of the
ifs is responsible for the
else. If we follow the rules that the
previous example suggests, then the second
is followed by a statement, and is therefore itself a statement, so the
else belongs to the first
That is not the way that C views it. The rule is that an
else belongs to the first if above that
hasn't already got an
In the example we're discussing, the else goes with the second if.
To prevent any unwanted association between an
else and an
if just above it, the if can be
hidden away by using a compound statement. To repeat the example in Chapter here it is.
Putting in all the compound statement brackets, it becomes this:if(expression)
If you happen not to like the placing of the brackets, it is up to you to put them where you think they look better; just be consistent about it. You probably need to know that this a subject on which feelings run deep.
while is simple:
is only executed if the expression
is non-zero. After every execution of the statement, the expression is evaluated again and the process
repeats if it is non-zero. What could be plainer than that? The only point to
watch out for is that the statement
may never be executed, and that if nothing in the statement affects the value
of the expression
while will either
do nothing or loop for ever, depending on the initial value of the expression.
It is occasionally desirable to guarantee at least one execution of the statement following the while, so an alternative form exists known as the do statement. It looks like this:do
and you should pay close attention to that
semicolon—it is not optional! The effect is that the statement part is executed
before the controlling expression is evaluated, so this guarantees at least one
trip around the loop. It was an unfortunate decision to use the keyword
while for both purposes, but it doesn't
seem to cause too many problems in practice.
If you feel the urge to use a
think carefully. It is undoubtedly essential in certain cases, but experience
has shown that the use of
statements is often associated with poorly constructed code. Not every time,
obviously, but as a general rule you should stop and ask yourself if you have
made the right choice. Their use often indicates a hangover of thinking methods
learnt with other languages, or just sloppy design. When you do
convince yourself that nothing else will give you just what is wanted, then go
ahead - be daring—use it.
A very common trick in C programs is to use the result of an
assignment to control
do loops. It is so
commonplace that, even if you look at it the first time and blench, you've got
no alternative but to learn it. It falls into the category of ‘idiomatic’ C and
eventually becomes second nature to anybody who really uses the language. Here
is the most common example of all:
The clever bit is the expression assigning to
input_c. It is assigned to, compared with
EOF (End Of File), and used to control
the loop all in one go. Embedding the assignment like that is a handy
embellishment. Admittedly it only saves one line of code, but the benefit in
terms of readability (once you have got used to seeing it) is quite large.
Learn where the parentheses are, too. They're necessary for precedence reasons—work
input_c is an
int. This is because
getchar has to be able to return not
only every possible value of a
but also an extra value,
To do that, a type longer than a
while and the
do statements are themselves
syntactically a single statement, just like an
if statement. They occur anywhere
that any other single statement is permitted. If you want them to control several
statements, then you will have to use a compound statement, as the examples of
A very common feature in programs is loops that are controlled by variables used as a counter. The counter doesn't always have to count consecutive values, but the usual arrangement is for it to be initialized outside the loop, checked every time around the loop to see when to finish and updated each time around the loop. There are three important places, then, where the loop control is concentrated: initialize, check and update. This example shows them.#include <stdio.h>
As you will have noticed, the initialization and check parts of the loop are
close together and their location is obvious because of the presence of the
while keyword. What is harder to spot is
the place where the update occurs, especially if the value of the controlling
variable is used within the loop. In that case, which is by far the most
common, the update has to be at the very end of the loop: far away from the
initialize and check. Readability suffers because it is hard to work out how
the loop is going to perform unless you read the whole body of the loop
carefully. What is needed is some way of bringing the initialize, check and
update parts into one place so that they can be read quickly and conveniently.
That is exactly what the for statement is designed to
do. Here it is.
The initialize part is an expression; nearly always an assignment expression which is used to initialize the control variable. After the initialization, the check expression is evaluated: if it is non-zero, the statement is executed, followed by evaluation of the update expression which generally increments the control variable, then the sequence restarts at the check. The loop terminates as soon as the check evaluates to zero.
There are two important things to realize about that last description: one, that each of the three parts of the for statement between the parentheses are just expressions; two, that the description has carefully explained what they are intended to be used for without proscribing alternative uses—that was done deliberately. You can use the expressions to do whatever you like, but at the expense of readability if they aren't used for their intended purpose.
Here is a program that does the same thing twice, the first time using a
while loop, the second time with a
The use of the increment operator is exactly the sort of use that you will see
in everyday practice.
There isn't any difference betweeen the two, except that in this case the
loop is more convenient and maintainable than the
while statement. You should always use the
for when it's
appropriate; when a loop is being controlled by some sort of counter. The
while is more at home when an
indeterminate number of cycles of the loop are part of the problem. As always,
it needs a degree of judgement on behalf of the author of the program; an
understanding of form, style, elegance and the poetry of a well written
program. There is no evidence that the software business suffers from a surfeit
of those qualities, so feel free to exercise them if you are able.
Any of the initialize, check and update expressions in the for statement can be omitted, although the semicolons must stay. This can happen if the counter is already initialized, or gets updated in the body of the loop. If the check expression is omitted, it is assumed to result in a ‘true’ value and the loop never terminates. A common way of writing never-ending loops is eitherfor(;;)
and both can be seen in existing programs.
The control of flow statements that we've just seen are
quite adequate to write programs of any degree of complexity. They lie at the
core of C and even a quick reading of everyday C programs will
illustrate their importance, both in the provision of essential functionality
and in the structure that they emphasize. The remaining statements are used to
give programmers finer control or to make it easier to deal with exceptional
conditions. Only the
statement is enough of a heavyweight to need no justification for its use; yes,
it can be replaced with lots of
but it adds a lot of readability. The others,
goto, should be treated
like the spices in a delicate sauce. Used carefully they can turn something
commonplace into a treat, but a heavy hand will drown the flavour of everything
This is not an essential part of C. You could do without it, but the language would have become significantly less expressive and pleasant to use.
It is used to select one of a number of alternative actions depending on the
value of an expression, and nearly always makes use of another of the lesser
looks like this.
is evaluated and its value is compared with all of the const1 etc.
expressions, which must all evaluate to different constant values (strictly
they are integral constant expressions, see Chapter 6 and below). If any
of them has the same value as the expression then the statement following the
case label is selected for execution. If
default is present, it
will be selected when there is no matching value found. If there is no
default and no matching value, the
switch statement will
do nothing and execution will continue at the following statement.
One curious feature is that the cases are not exclusive, as this example shows.#include <stdio.h>
The loop cycles with
having values 0–10. A value of
printf statements. What you might not
expect is the way that the remaining messages would also appear! It's because
switch only selects one
entry point to the body of the statement; after starting at a given point all
of the following statements are also executed. The
default labels simply allow you to indicate which
of the statements is to be selected. When
has the value of
The labels can occur in any order, but no two values may be the same and you
are allowed either one or no
(which doesn't have to be the last label). Several labels can be put in front
of one statement and several statements can be put after one label.
The expression controlling the
can be of any of the integral types. Old C used to insist on only
int here, and some compilers
would forcibly truncate longer types, giving rise on rare occasions to some
very obscure bugs.
The biggest problem with the
statement is that it doesn't allow you to select mutually exclusive courses of
action; once the body of the statement has been entered any subsequent
statements within the body will all be executed. What is needed is the
break statement. Here is the previous
example, but amended to make sure that the messages printed come out in a more
sensible order. The
statements cause execution to leave the
statement immediately and prevent any further statements in the body of the
switch from being executed.
break has further
uses. Its own section follows soon.
Although Chapter deals with constant expressions, it is worth looking briefly at
what an integral constant expression is, since that is what must follow the
case labels in a
switch statement. Loosely speaking, it
is any expression that does not involve any value-changing operation (like
increment or assignment), function calls or comma operators. The operands in
the expression must all be integer constants, character constants, enumeration
and floating-point constants that are the immediate operands of casts. Any cast
operators must result in integral types.
Much what you would expect, really.
This is a simple statement. It only makes sense if it occurs in the body of
for statement. When it is
executed the control of flow jumps to the statement immediately following the
body of the statement containing the
Its use is widespread in
statements, where it is more or less essential to get the control that most
The use of the
within loops is of dubious legitimacy. It has its moments, but is really only
justifiable when exceptional circumstances have happened and the loop has to be
abandoned. It would be nice if more than one loop could be abandoned with a
single break but that isn't how it works. Here is an example.
It reads a single character from the program's input before printing the
next in a sequence of numbers. If an ‘
s’ is typed, the break causes an
exit from the loop.
If you want to exit from more than one level of loop, the
break is the wrong thing to use. The
goto is the only easy way, but since it
can't be mentioned in polite company, we'll leave it till last.
This statement has only a limited number of uses. The rules for its use are
the same as for
the exception that it doesn't apply to
statements. Executing a
starts the next iteration of the smallest enclosing
immediately. The use of
is largely restricted to the top of loops, where a decision has to be made
whether or not to execute the rest of the body of the loop. In this example it
ensures that division by zero (which gives undefined behaviour) doesn't happen.
You could take a puritanical stance and argue that, instead of a conditional
continue,, the body of the loop should be
made conditional instead—but you wouldn't have many supporters. Most C
programmers would rather have the
continue than the extra level of
indentation, particularly if the body of the loop is large.
Of course the
can be used in other parts of a loop, too, where it may occasionally help to
simplify the logic of the code and improve readability. It deserves to be used
Do remember that
has no special meaning to a
have. Inside a
continue is only valid if there is a
loop that encloses the
in which case the next iteration of the loop will be started.
There is an important difference between loops written with
for. In a
a continue will go immediately to the test of the
controlling expression. The same thing in a
for will do two things: first the
update expression is evaluated, then the controlling expresion is evaluated.
Everybody knows that the
statement is a ‘bad thing’. Used without care it is a great way of making
programs hard to follow and of obscuring any structure in their flow. Dijkstra
wrote a famous paper in 1968 called ‘Goto Statement Considered Harmful’, which
everybody refers to and almost nobody has read.
What's especially annoying is that there are times when it is the most
appropriate thing to use in the circumstances! In C, it is used to escape
from multiple nested loops, or to go to an error handling exit at the end of a
function. You will need a label when you use a
goto; this example shows both.
A label is an identifier followed by a colon. Labels have their own ‘name
space’ so they can't clash with the names of variables or functions. The name
space only exists for the function containing the label, so label names can be
re-used in different functions. The label can be used before it is declared,
too, simply by mentioning it in a
Labels must be part of a full statement, even if it's an empty one. This usually only matters when you're trying to put a label at the end of a compound statement—like this.label_at_end /* empty statement */
goto works in an
obvious way, jumping to the labelled statements. Because the name of the label
is only visible inside its own function, you can't jump from one function to
It's hard to give rigid rules about the use of
gotos but, as with the
continue and the
break (except in
switch statements), over-use should be
avoided. Think carefully every time you feel like using one, and convince
yourself that the structure of the program demands it. More than one
goto every 3–5 functions is a symptom
that should be viewed with deep suspicion.
Now we've seen all of the control of flow statements and examples of their use. Some should be used whenever possible, some are not for use line by line but for special purposes where their particular job is called for. It is possible to write elegant and beautiful programs in C if you are prepared to take the extra bit of care necessary; the specialized control of flow statements give you the chance to add the extra polish that some other languages lack.
All that remains to be done to complete the picture of flow of control in C is to finish off the logical operators.
Politica de confidentialitate|
Adauga cod HTML in site