Flow Control Structures
From Rosetta Code
Programming Task
This is a programming task. It lays out a problem which Rosetta Code users are encouraged to solve, using languages they know.
These are examples of control structures. You may also be interested in:
- Conditional Structures
- Exceptions
- Flow Control Structures
- Loop Structures
In this task, we document common flow-control structures. One common example of a flow-control structure is the goto construct. Note that Conditional Structures and Loop Structures have their own articles.
Contents |
[edit] Ada
[edit] goto
Top:
Put_Line("Hello, World");
goto Top;
[edit] exit
Exit is used to break out of loops. Exit can be used with a label to break out of an inner loop to an outer loop and its enclosing outer loop
Outer:
loop
-- do something
loop
-- do something else
exit Outer; -- exits both the inner and outer loops
end loop;
end loop;
[edit] C
[edit] goto
One common use of goto in C is to break out of nested loops.
int main()
{
int i,j;
for (j=1; j<1000; j++) {
for (i=0; i<j, i++) {
if (exit_early())
goto out;
/* etc. */
}
}
out:
return 0;
}
[edit] C++
[edit] goto
Works with: GCC version 3.3.4
#include <iostream>
int main()
{
LOOP:
std::cout << "Hello, World!\n";
goto LOOP;
}
Note that "goto" may also be used in conjunction with other forms of branching.
[edit] Exceptions
Works with: GCC version 4.0.2
Exceptions are a way to give control back to a direct or indirect caller in case of an error. Note that throwing exceptions is usually very expensive, therefore they generally should only be used for exceptional situations.
#include <iostream>
#include <ostream>
void foo()
{
std::cout << "Going to throw an exception.\n";
throw 7; // almost any object can be thrown, including ints
std::throw << "This output will never execute.\n";
}
void bar()
{
std::cout << "Going to call foo().\n";
foo();
std::cout << "This will be skipped by the exception coming from foo.\n";
}
void baz()
{
try // everything thrown from inside the following code block
{ // will be covered by the following catch clauses
std::cout << "Going to call bar().\n";
bar();
std::cout << "This will be skipped by the exception coming from foo.\n";
}
catch(...) // a simple catch-all, but doesn't give access to the thrown exception
{
std::cout << "An exception occured. I'll just throw it on.\n";
throw; // without an argument, the caught exception is re-thrown
}
std::cout << "This will not be executed due to the re-throw in the catch block\n";
}
void foobar()
{
try
{
baz();
}
catch(char const* s)
{
std::cout << "If foo had thrown a char const*, this code would be executed.\n";
std::cout << "In that case, the thrown char const* would read " << s << ".\n";
}
catch(int i)
{
std::cout << "Caught an int, with value " << i << " (should be 7).\n";
std::cout << "Not rethrowing the int.\n";
}
catch(...)
{
std::cout << "This catch-all doesn't get invoked because the catch(int) above\n"
<< "already took care of the exception (even if it had rethrown the\n"
<< "exception, this catch-all would not be invoked, because it's\n"
<< "only invoked for exceptions coming from the try block.\n";
}
std::cout << "This will be executed, since the exception was handled above, and not rethrown.\n";
}
int main()
{
try
{
foobar();
}
catch(...)
{
std::cout << "The main function never sees the exception, because it's completely handled\n"
<< "inside foobar(). Thus this catch-all block never gets invoked.\n";
}
}
[edit] Forth
[edit] CATCH-THROW
Forth does not have goto, but the standard does have an exception mechanism.
: checked-array
CREATE ( size -- ) DUP , CELLS ALLOT
DOES> ( i -- a+i )
2DUP @ 0 SWAP WITHIN IF
SWAP 1+ CELLS +
ELSE
1 THROW
THEN ;
8 checked-array myarray
: safe-access ( i -- a[i] )
['] myarray CATCH 1 = IF ." Out of bounds!" 0 THEN ;
[edit] IDL
[edit] goto
test: ..some code here goto, test
(This is almost never used)
[edit] on_error
on_error, test
(This resumes at the label test if an error is encountered)
[edit] on_ioerror
on_ioerror, test
(Same as on_error, but for EOFs and read-errors and such)
[edit] break
break
immediately terminates the innermost current loop (or if or case etc)
[edit] continue
continue
immediately starts the next iteration of the current innermost loop
[edit] Java
"goto" is a reserved keyword in Java; but you cannot use it. There are currently no goto statements.
[edit] Perl
Works with: Perl version 5.x
[edit] goto
Goto is typically looked down upon by most Perl programmers
FORK: # some code goto FORK;
[edit] Pop11
[edit] quitloop
quitloop with argument exits from nested loops:
while condition1 do
while condition2 do
if condition3 then
quitloop(2);
endif;
endwhile;
endwhile;
above quitloop(2) exits from both loops.
[edit] goto
goto l transfers control to the label l. goto may be used to exit from nested loops:
while condition1 do
while condition2 do
if condition3 then
goto l;
endif;
endwhile;
endwhile;
l:;
Another use is to implement finite state machines:
state1:
DO_SOMETHING();
if condition1 then
goto state1;
elseif condition2 then
goto state2;
....
else
goto stateN;
endif;
state2:
....
...
...
stateN:
....
Pop11 goto is a nonlocal one, so "jump out" from a chain of procedure calls:
define outer();
define inner(n);
if n = 0 then
goto final;
endif;
inner(n - 1);
enddefine;
inner(5);
final:;
enddefine;
This is useful to exit early from successful recursive search, and for exception handling.
[edit] go_on
go_on is a multiway jump
go_on expression to lab1, lab2, ..., labN else elselab ;
If expression has value K the above will jump to label labK, if expression is not an integer, or if it outside range from 1 to N, then control passes to label elselab. The else part may be omitted (then out of range values of expression cause an exception).
There is a more structured variant of go_on:
go_on expression to lab :
lab 1 : statement1; lab 2 : statement2; ....
endgo_on;
where lab is a prefix chosen by the user.
[edit] return
return ends execution of current function. In simplest form it is just:
return;
but it is also possible to specify one or more return values:
return(val1, val2, val3);
[edit] chain
chain has effect of "tail call" but is not necessarily in tail position. More precisely inside proc1.
chain proc2(x1, x2, x3);
finishes execution of proc1 and transfers control to the proc2 passing it x1, x2, and x3 as arguments. On return from proc2 control passes to caller of proc1.
Remark: Pop11 does not perform "tail call optimization", one has to explicitly use chain.
[edit] Python
[edit] Exceptions
# Flow Control Structures in Python (Exceptions) # Exceptions are handled by the following operators: # try, except, finally, break, and continue, etc. # See each case for details... import math def main():
[edit] Case 1 - Try, Except
try:
temp = 0/0
# 'except' catches any errors that may have been raised between the code of 'try' and 'except'
except:
print "An error occurred."
# Output : "An error occurred"
[edit] Case 2 - Try, Except
try:
temp = 0/0
# here, 'except' catches a specific type of error raised within the try block.
except ZeroDivisionError:
print "You've divided by zero!"
# Output : "You've divided by zero!"
[edit] Case 3 - Try, Except, Finally
try:
temp = 0/0
except:
print "An error occurred."
# here, 'finally' executes when the try - except block ends, regardless of whether an error was raised or not
# useful in areas such as closing opened file streams in the try block whether they were successfully opened or not
finally:
print "End of 'try' block..."
# Output :
# An error occurred
# End of 'try' block...
[edit] Case 4 - Try, Except within a function
def divisionbyzero(): # create a function that is sure to fail
temp = 0/0
try:
divisionbyzero()
except ZeroDivisionError:
print "You've divided by zero!"
# Output :
# You've divided by zero!
[edit] Case 5 - Try, Except, Else
try:
temp = 1/1 # not a division by zero error
except ZeroDivisionError: # so... it is not caught
print "You've divided by zero."
# here, 'else' executes when no exceptions are caught...
else:
print "No apparent error occurred."
# Output :
# No apparent error occurred.
[edit] Case 6 - Try, Except, break, continue
i = 0
while 1: # infinite loop
try:
temp2 = 0/i # will raise a ZeroDivisionError first.
temp = math.sqrt(i)
break # 'break' will break out of the while loop
except ValueError: #
print "Imaginary Number! Breaking out of loop"
break # 'break' out of while loop
except ZeroDivisionError:
print "You've divided by zero. Decrementing i and continuing..."
i-=1 # we decrement i.
# we 'continue', everything within the try - except block will be executed again,
# this time however, ZeroDivisionError would not be raised again.
continue # Note that removing it, replacing it with 'pass' would perform the equivalent
# see below for a better example
# Output :
# You've divided by zero. Decrementing i and continuing...
# Imaginary Number! Breaking out of loop
[edit] Case 7 - Creating your own custom exceptions, raise
# Let's call our custom error "StupidError"; it inherits from the Exception class
class StupidError(Exception): pass
# Try it out.
try:
raise StupidError("Segfault") # here, we manually 'raise' the error within the try block
except StupidError, details: # 'details' is the StupidError object we create in the try block.
print 'Something stupid occurred:', details # so we access the value we had stored for it...
# Output :
# Something stupid occurred: Segfault
[edit] Case 8 - continue, else in "for" loop
i = 101
for i in range(0,4): # loop 4 times
print "I will always be seen."
continue # continue goes back to the loop beginning for a new iteration.
print "I'll never be seen."
else:
print "Loop done"
# Output:
# I will always be seen.
# I will always be seen.
# I will always be seen.
# I will always be seen.
# Loop done
if(__name__ == "__main__"):
main()
[edit] The "with" statement
Works with: Python version 2.6
See [PEP 0343, The "with" statement]
>>> with open("some_file"): # file ``some_file`` is closed after ``with`` block in any case whether an exception is raised or not
... raise Exception("an error")
[edit] Yield expressions
Works with: Python version 2.5
See [PEP 0342, Coroutines via Enhanced Generators]
>>> value = 1 >>> echo = lambda: (yield value) >>> for i in echo(): ... print i ... 1
[edit] Tcl
[edit] exception
Tcl's catch command can be used to provide a basic exception-handling mechanism:
if {[catch { ... code that might give error ... } result]} {
puts "Error was $result"
} else {
... process $result ...
}
[edit] custom control structures
A novel aspect of Tcl is that it's relatively easy to create new control structures (more detail at http://wiki.tcl.tk/685). Eg. defining a command to perform some operation for each line of an input file:
proc forfilelines {linevar filename code} {
upvar $linevar line ; # connect local variable line to caller's variable
set filechan [open $filename]
while {[gets $filechan line] != -1} {
uplevel 1 $code ; # Run supplied code in caller's scope
}
close $filechan
}
Now use it to print the length of each line of file "mydata.txt":
forfilelines myline mydata.txt {
puts [string length $myline]
}
Categories: Less Than 20 Examples | Programming Tasks | Control Structures | Ada | C | C++ | Forth | IDL | Java | Perl | Pop11 | Python | Tcl

