AutoIt教程:5. 函数

by xiaolai on 2010/04/30 · 18 comments

in Auto-It

新的知识必然与过往的任何知识都不同,否则它就不“新”了。“类比思考”可以帮我们运用已有的知识对比着了解新的知识,然而很多的时候,要更多甚至全然关注于“不同”之处才行。另外,如果遇到的是“仅仅看起来像已知的某样东西而已,可实际上却全然不同的”新知识,那么“类比思考”就不适用了。而思考之时,“类比”无所不在,于是,控制它需要一些挣扎……

编程语言中的函数(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 }

lwzz April 30, 2010 at 16:34

更新真快……

Reply

et April 30, 2010 at 17:15

很有趣,这样大分量的好文章留言支持的这么少?!

鼓励一下李老师,谢谢,这样的东西提高效率很有帮助。

Reply

杨熙锟 April 30, 2010 at 17:17

编程语言里的函数和数学里的函数差别很大么? 感觉都是给若干个输入, 然后得到一个输出啊…

Reply

lwzz April 30, 2010 at 17:17

讲一道小学数学题:
小白兔搜不到胡萝卜了,很着急,于是去买了青菜。已知,青菜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)

Reply

lwzz April 30, 2010 at 17:22

竟然把加法和乘法搞错了,晕倒……

Reply

李笑来 April 30, 2010 at 21:35

很好的“bug”防不胜防的例子。:)

Reply

杨熙锟 April 30, 2010 at 17:28

呃… 我居然忘了还有没有返回值的函数…

Reply

nisky April 30, 2010 at 21:36

是啊,我还记得以前学objective pascal的时候,有返回值的叫function,没有返回值的叫procedure

Reply

nisky April 30, 2010 at 21:41

写错了,应该是object pascal

Reply

南通SEO May 1, 2010 at 22:03

笑来老师的学力能力,值得学习

Reply

小强 May 9, 2010 at 21:27

笑来老师,

为什么您的函数前面要加两个下划线呢?

这种命名规则有什么好处么?我理解是用于区分内部函数 ?

Reply

hnbc1 May 9, 2010 at 22:02

一个数学函数也是一组规则,把一个集合中的元素投射到另一个集合中去。这和编程语言中的函数没有区别,本质都是一组规则。

Reply

李笑来 May 9, 2010 at 23:15

那程序中没有参数的函数呢?对应着什么?

Reply

李笑来 May 9, 2010 at 23:15

那程序中没有参数的函数呢?对应着什么?

Reply

fox June 25, 2010 at 13:28

中文的“函数”是一个范围比较狭窄的概念,不像英文 function 的含义那么多。

把一段具有特定功能的代码封装起来,就是程序设计语言中的 function 了,它和数学里的 function 是有一定关系的——如果这段代码具有参数返回值,那么它就和数学中典型的函数非常接近了。即使只具有二者之一,也可以类比成常值函数。

参数和自变量两者都不具备的 function,没法和数学里面的函数类比,但是它仍然是一个 function,因为它具有一定的“目的”和“功能”,“运作”的时候会起一定的“作用”…… function 这个词的含义可不仅仅是“函数”。不要被中文翻译给限制住了。把程序设计语言里面的 function 统统翻译成“函数”并不很恰当。

不过外国人大概也会对此感到纠结,所以在有些语言里面搞出了 function 和 procedure 的区分。也有相反的情况。了解 Scheme 或者 Haskell 语言的朋友大概对 function 这个东西更有体会了。

Reply

September 20, 2010 at 15:22

学习了。。。。非常好。

Reply

haoask October 28, 2010 at 11:30

简单易懂,支持

Reply

Jinson November 15, 2010 at 17:12

Good !

Reply

Leave a Comment

Previous post:

Next post: