前面的分析为我们的函数定义提供了骨架:首先,我们需要一个变量,我们可以称之为 total
,它将是函数返回的总的鹅卵石数量。这将是函数返回的值。
其次,我们知道函数将需要一个参数:这个参数将是三角形中的总行数。它可以被称为 number-of-rows
。
最后,我们需要一个作为计数器的变量。我们可以称这个变量为 counter
,但更好的名字是 row-number
。这是因为在这个函数中,计数器的作用是计算行数,而程序应该尽可能易于理解。
当Lisp解释器首次开始评估函数中的表达式时,total
的值应该设置为零,因为我们还没有向其中添加任何东西。然后,函数应该将第一行中的鹅卵石数量添加到总数中,然后将第二行的数量添加到总数中,然后将第三行的数量添加到总数中,依此类推,直到没有更多的行可以添加。
total
和row-number
都仅在函数内部使用,因此它们可以被声明为局部变量,并用let
给予初始值。显然,total
的初始值应为0。row-number
的初始值应为1,因为我们从第一行开始。这意味着let
语句将如下所示:
(let ((total 0) (row-number 1)) body…)
在内部变量被声明并绑定到它们的初始值之后,我们可以开始while
循环。作为测试的表达式应该在row-number
小于或等于number-of-rows
时返回true。如果表达式仅在行号小于三角形行数的情况下为true,最后一行将永远不会添加到总数中;因此行号必须小于或等于行数。
Lisp提供了<=
函数,如果其第一个参数的值小于或等于其第二个参数的值,则返回true,否则返回false。因此,while
将评估为测试的表达式应如下所示:
(<= row-number number-of-rows)
鹅卵石的总数量可以通过重复将一行中的鹅卵石数量添加到已找到的总数中来找到。由于一行中的鹅卵石数量等于行号,因此可以通过将行号添加到总数中来找到总数。
(setq total (+ total row-number))
这做的是将total
的新值设置为将鹅卵石数量添加到先前总数的和。
在设置了total
的值之后,需要建立下一次循环的条件,如果有的话。这是通过增加row-number
变量的值来完成的,它充当计数器。在增加row-number
变量之后,while
循环开头的true-or-false测试会测试其值是否仍然小于或等于number-of-rows
的值,如果是,将新值添加到先前循环的total
中。
内置的Emacs Lisp函数1+
将1添加到一个数字,因此可以使用以下表达式递增row-number
变量:
(setq row-number (1+ row-number))