5.6 函数的功能

下面的第3行代码是一次函数调用,称为调用func函数
a=6
b=func(a)
print(b)
函数的调用,,也可以在别的函数。例如A函数调用了B函数,然后又调用了A函数。现在我们要学会这样来“使用”函数。
看下面的题目: 定义一个函数,以一个整数为参数,返回该整数的绝对值。 这个函数能得到一个数字的绝对值,假设这个函数的名称是abs。
现在看下面的例子: 函数f(x)=x*x+5|x|+6和g(x)=x*x-|x|,x的类型是整数。 f和g两个函数都需要计算绝对值,我们可以使用已经写好的绝对值函数,来完成这两函数:
def abs(x):
    if x>0:
       return x
    else:
       return -x
def f(x):
    y=x*x+5*abs(x)+6
    return y
def g(x):
    return x*x-abs(x)
print(f(5))
print(g(5))

这其实就是函数最根本的作用:函数把功能单元抽象出来,需要的时候就可以使用。

abs(x)函数是得到x的绝对值,然后f调用了abs函数(第9行代码)。最后调用f函数,参数是5,打印出了最终计算结果。
如果把所有代码都到一个函数里面,那么就会复杂一点,同时会有重复的代码存在,这类冗余代码是要避免的。 例如f函数不用abs函数的话,那么就会变成这样:
def f(x):
    if x > 0:
        z = x
    else:
        z = -x  
    y = x * x + 5 * z + 6
    return y
def g(x):
    if x > 0:
        z = x
    else:
        z = -x 
    return x * x-z
第2到第4行代码就是计算x的绝对值,z的值就是x的绝对值。第11和14也是计算绝对值。这就是代码冗余。
代码冗余有什么坏处呢?
1.多余代码。
2.难以维护。需要修改的时候,就需要查找所有使用过的地方,然后修改!在这个例子里,绝对值的计算不会改变,但假如是一些复杂一点的逻辑。如果找到了更好的算法,需要替换,那么需要找到所有用过旧算法的代码,然后替换,不仅容易出错,还容易漏掉(想象一下某个代码片段在各处用了20次)。

其实,函数的最主要作用是:将复杂问题化成若干个简单函数,然后逐个解决。
下面我们来用这个分解问题的方法,来解决这个问题: 输入两个数字,求它们的最大公约数。
最大公约数是两个数字都能整除的最大数字。
解题思路是这样的:
1.i从2开始,定义max为1,max就是最终的最大公约数,num为两个数较小的数字
2.假如i小于等于num,进入第3步,否则算法结束,max就是最大公约数
3.判断i能不能被两个数整除,如果能,将i的值赋给max。进入第4步。
4.i加1,回到第2步

关于这些初值这么设置,是这样的原因:
i没必要从1开始,因为1必定能被任何整数整除,
max初值设定为1,如果max的值一直都没有改变,那么1就是两个数的最大公约数,所以max的初值不能随便设置(例如设为0是不行的)
num设置为两个数中较小的数,是为了减少循环次数。

可分解成下面这些函数:
min(a,b),返回a和b较小的那个数。
canBeDivide(a,b),a能被b整除,返回True,否则返回False
下面我们来实现它们,最终通过函数调用,完成最大公约数。