新的知识必然与过往的任何知识都不同,否则它就不“新”了。“类比思考”可以帮我们运用已有的知识对比着了解新的知识,然而很多的时候,要更多甚至全然关注于“不同”之处才行。另外,如果遇到的是“仅仅看起来像已知的某样东西而已,可实际上却全然不同的”新知识,那么“类比思考”就不适用了。而思考之时,“类比”无所不在,于是,控制它需要一些挣扎……
编程语言中的函数(Function)和数学里的函数(你肯定学过一些的)压根就不是一回事儿,它们只是“恰巧”名字相同而已。(这就好像“table”这个概念可以指两个完全没关系的概念一样──“桌子”和“表格”。看,我们又是用类比进行理解……只不过,这次没什么问题。)
在程序里,所谓函数,本质上来看就是一段有特定功能的代码。一个函数由以下几个部分构成:
- 函数名
- 参数
- 返回值
- 定义
- 调用
在这里停上三五分钟,把这五个要素牢牢记住──靠死记硬背,在你还不知道它们究竟指什么之前,就先把这几个名称牢牢记住。要做到有人问你“函数构成有几个部分?”的时候,你脱口而出这五个名称……然后再继续阅读下去。
新建一个AutoIt文件,将其命名为Testing12.au3,输入以下代码:
Func __AddUpTo($n) $r = 0 For $i = 1 To $n $r = $r + $i Next Return $r EndFunc
按F5执行,这段代码不输出任何结果。
这段代码只是定义了一个函数,定义函数的语法是:Func…EndFunc:
- 它的函数名为__AddUpTo()
- 调用这个函数时,需要提供一个参数
- 这个函数的返回值是(1+2+3…+n)的值
再补上两行,使其变成这个样子:
Func __AddUpTo($n) $r = 0 For $i = 1 To $n $r = $r + $i Next Return $r EndFunc $result = __AddUpTo(100) MsgBox(0, "Result", $result)
按F5查看结果:

当计算机阅读你的指示(即,你写的程序)之时,读到第一行,它看到Func,就知道你是在定义一个函数,它“理解”了,然后找到EndFun,看看后面有没有“可执行”的代码……
而后,它在第8行,读到了一个函数“调用”,即,你向__AddUpTo()这个函数传递了一个参数(100)。
它在当前文件中去寻找有没有这个函数的定义(当然有,在第1行定义的……),找到之后,开始执行__AddUpTo()这个函数区块中(Func … EndFunc)的内容……
此时,$n = 100,因为你刚刚在调用__AddUpTo()的时候,在括号里写了100,所以,在Func __AddUpTo($n)开始执行的时候,$n 被赋值为 100。
而后内部的运算,你都看得懂,最终的结果是变量$r的值为5050(1+2+3…+100)
然后,函数__AddUpTo()把根据传递进来的参数(100)计算出来的结果(5050)返回给第8行的代码,“$result = __AddUpTo(100)”,即,从此之后,变量$result的值就是5050。
再然后,第9行代码呼出一个对话框,显示结果……
现在,新建一个AutoIt文件,将其命名为Testing13.au3,输入以下代码:
Func __AddFromUpTo($a, $b) $r = 0 For $i = $a To $b $r = $r + $i Next Return $r EndFunc $result = __AddFromUpTo(101, 200) MsgBox(0, "Result", $result)
这次我们定义的函数名称叫__AddFromUpTo(),它需要两个参数,返回值是从第一个参数加到第二个参数究竟等于多少:

现在,尝试一下,把Testing13.au3第9行的代码改为:
$result = __AddFromUpTo(200)
而后按F5执行,结果是跳出一个“出错提示”对话框:
这是因为当初定义__AddFromUpTo()就指明调用它的时候需要提供两个参数,而现在却只提供了一个参数,所以,计算机“糊涂”了,弄不明白你究竟想干什么……
新建一个AutoIt文件,将其命名为Testing14.au3,输入以下代码(不要按F5查看结果,而是先尝试着用脑演练一番,看看自己能不能想出正确结果……):
Func __AddFromUpTo($a=1, $b=100) $r = 0 For $i = $a To $b $r = $r + $i Next Return $r EndFunc $result = __AddFromUpTo() MsgBox(0, "Result", $result) $result = __AddFromUpTo(50) MsgBox(0, "Result", $result) $result = __AddFromUpTo(101,200) MsgBox(0, "Result", $result)
这一次,我们在定义__AddFromUpTo()之时,为它的两个参数都提供了“默认值”,第一个参数默认是1,第二个参数默认是2。即,如果在调用这个函数的时候并未向其传递参数的话,那么就使用默认值进行运算(并返回相应的结果)。所以,
- 调用__AddFromUpTo(),相当于没有提供任何参数,所以它按默认值运算,返回的应该是(5050);
- 调用__AddFromUpTo(50),相当于向__AddFromUpTo()函数提供了第一个参数(50),而第二个参数由于未被提供,所以采用默认值(100),于是,这个函数调用所返回的应该是3825(50+51+52…100);
- 调用__AddFromUpTo(101,200),向该函数提供了它所需要的全部两个参数,所以,该函数内部的运算不使用任何默认值,而是计算从101加到200的结果,并返回(15050)。
现在按F5查看一下执行结果:



现在,再回顾一下我们刚刚遇到的一些概念:
- 函数名
- 参数、默认参数
- 返回值
- 定义
- 调用
作业:
重新去反复阅读若干遍ConsoleWrite()、InputBox()和MsgBox()这三个函数的帮助文档。




{ 18 comments… read them below or add one }
更新真快……
很有趣,这样大分量的好文章留言支持的这么少?!
鼓励一下李老师,谢谢,这样的东西提高效率很有帮助。
编程语言里的函数和数学里的函数差别很大么? 感觉都是给若干个输入, 然后得到一个输出啊…
讲一道小学数学题:
小白兔搜不到胡萝卜了,很着急,于是去买了青菜。已知,青菜1大洋一把,小白兔买了2把一共花了多少钱?
解: 设青菜价格为a,购买数量为b,花费为c,由题意得
a + b = c
已知青菜价格为1,购买数量为2,代入数据可得:
1×2 =2 (大洋)
答:小白兔花了2大洋。
函数的参数类似于数学的:已知条件
返回值类似于:答
Func __xiaobai2($a,$b)
$c = $a + $b;
Return $c
EndFunc
$result = __xiaobai2(1,2)
MsgBox(0, “Result”, $result)
竟然把加法和乘法搞错了,晕倒……
很好的“bug”防不胜防的例子。:)
呃… 我居然忘了还有没有返回值的函数…
是啊,我还记得以前学objective pascal的时候,有返回值的叫function,没有返回值的叫procedure
写错了,应该是object pascal
笑来老师的学力能力,值得学习
笑来老师,
为什么您的函数前面要加两个下划线呢?
这种命名规则有什么好处么?我理解是用于区分内部函数 ?
一个数学函数也是一组规则,把一个集合中的元素投射到另一个集合中去。这和编程语言中的函数没有区别,本质都是一组规则。
那程序中没有参数的函数呢?对应着什么?
那程序中没有参数的函数呢?对应着什么?
中文的“函数”是一个范围比较狭窄的概念,不像英文 function 的含义那么多。
把一段具有特定功能的代码封装起来,就是程序设计语言中的 function 了,它和数学里的 function 是有一定关系的——如果这段代码具有参数和返回值,那么它就和数学中典型的函数非常接近了。即使只具有二者之一,也可以类比成常值函数。
参数和自变量两者都不具备的 function,没法和数学里面的函数类比,但是它仍然是一个 function,因为它具有一定的“目的”和“功能”,“运作”的时候会起一定的“作用”…… function 这个词的含义可不仅仅是“函数”。不要被中文翻译给限制住了。把程序设计语言里面的 function 统统翻译成“函数”并不很恰当。
不过外国人大概也会对此感到纠结,所以在有些语言里面搞出了 function 和 procedure 的区分。也有相反的情况。了解 Scheme 或者 Haskell 语言的朋友大概对 function 这个东西更有体会了。
学习了。。。。非常好。
简单易懂,支持
Good !