To reinforce what we have learned so far, below is a longer example that uses a

while loop to compute the factorial function:

Example 1–13 A while loop to compute factorial.

proc Factorial {x} {

set i 1; set product 1

while {$i <= $x} {

set product [expr $product * $i]

incr i

}

return $product

}

Factorial 10

=> 3628800

The semicolon is used on the first line to remind you that it is a command

terminator just like the newline character. The while loop is used to multiply all

the numbers from one up to the value of x. The first argument to while is a boolean

expression, and its second argument is a command body to execute. The

while command and other control structures are described in Chapter 6.

The same math expression evaluator used by the expr command is used by

while to evaluate the boolean expression. There is no need to explicitly use the

expr command in the first argument to while, even if you have a much more

complex expression.

The loop body and the procedure body are grouped with curly braces in the

same way. The opening curly brace must be on the same line as proc and while.

If you like to put opening curly braces on the line after a while or if statement,

you must escape the newline with a backslash:

while {$i < $x} \

{

set product ...

}

Always group expressions and command bodies with curly braces.

More about Variables 13

I. Tcl Basics

Curly braces around the boolean expression are crucial because they delay

variable substitution until the while command implementation tests the expression.

The following example is an infinite loop:

set i 1; while $i<=10 {incr i}

The loop will run indefinitely.* The reason is that the Tcl interpreter will

substitute for $i before while is called, so while gets a constant expression 1<=10

that will always be true. You can avoid these kinds of errors by adopting a consistent

coding style that groups expressions with curly braces:

set i 1; while {$i<=10} {incr i}

The incr command is used to increment the value of the loop variable i.

This is a handy command that saves us from the longer command:

set i [expr $i + 1]

The incr command can take an additional argument, a positive or negative

integer by which to change the value of the variable. Using this form, it is possible

to eliminate the loop variable i and just modify the parameter x. The loop

body can be written like this:

while {$x > 1} {

set product [expr $product * $x]

incr x -1

}

Example 1–14 shows factorial again, this time using a recursive definition.

A recursive function is one that calls itself to complete its work. Each recursive

call decrements x by one, and when x is one, then the recursion stops.

Example 1–14 A recursive definition of factorial.

proc Factorial {x} {

if {$x <= 1} {

return 1

} else {

return [expr $x * [Factorial [expr $x - 1]]]

}

}

## No comments:

Post a Comment