A Factorial Example

   

Practical Programming in Tcl & Tk, Third Edition
By Brent B. Welch

Table of Contents
Chapter 1.  Tcl Fundamentals


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 ... } 

graphics/tip_icon.gif

Always group expressions and command bodies with curly braces.


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:

[*] Ironically, Tcl 8.0 introduced a byte-code compiler, and the first releases of Tcl 8.0 had a bug in the compiler that caused this loop to terminate! This bug is fixed in the 8.0.5 patch release.

 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]]]    } } 

       
    Top
     



    Practical Programming in Tcl and Tk
    Practical Programming in Tcl and Tk (4th Edition)
    ISBN: 0130385603
    EAN: 2147483647
    Year: 1999
    Pages: 478

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net