欢迎光临散文网 会员登陆 & 注册

第八章 函数-1

2023-07-06 21:48 作者:wangyanhpa  | 我要投稿

到现在为止,我们学完了Python的基础知识和程序的三种控制结构,函数这一章是帮助我们向更高的程序设计阶段进发,一般说来,所有的程序设计语言里都有函数(有的语言称为模块),这是为什么呢?

想想第三章我们介绍了内置函数,为啥要有内置函数呢?因为这些功能经常要用到,所以编写成一个函数供大家使用。但是这些函数都是通用功能,比如数学函数、字符串函数等等。不同领域常用功能不同,所以不同专业需要自己的函数,我们编写完函数之后还可以给其他人用,这就是代码复用。其实我们自己编写程序也应该是把写过的代码保存好,万一以后用到呢?梦想还是要有的,万一实现了呢。

8.1 函数定义

函数是一种仅在调用时运行的代码块。可以将数据(称为参数)传递到函数中,函数可以把数据作为结果返回。具体的语法如下:

def 函数名([参数列表]):

#实现特定功能的多行代码

[return [返回值]]

参数列表是用逗号分隔的标识符,[ ]表示括起来的部分可以有也可以没有,所以参数可以没有,返回值可以没有,不带表达式的return相当于返回 none。

我们先看一个例子,输出一行星号。

def displayStar():

    print("**********************")

这里函数名为displayStar,函数没有参数,没有返回值。函数功能为打印一行星号的语句。

函数头为def displayStar():

函数体为函数头部下方有缩进的部分,这里只有一条语句print("**********************")。

在PyCharm里输入上述函数之后运行程序,没有任何输出结果,因为displayStar函数没有被调用,所以不会执行函数里的函数体代码。

学过函数之后,我们需要学会定义一个main()函数,在main函数中编写代码调用定义好的函数,然后在程序中调用main函数。这样程序执行就会先执行main函数,如果main函数中调用了其它函数,则程序转向调用的函数执行该函数的函数体,调用结束之后,返回到调用的位置继续执行下面的代码。程序的执行过程总结一下就是:当程序调用一个函数时,程序控制权就会转移到被调用的函数上。当执行完函数的返回语句或执行到函数结束时,被调用函数就会将程序控制权交还给调用者。

为了执行displayStar函数,我们还需要编写main函数,在main函数中调用displayStar函数,具体代码如下:

def displayStar():

    print("displayStar begin")

    print("**********************")

    print("displayStar end")

 

def main():

    print("main begin")

    displayStar()

    print("main end")

 

main()

 

运行程序结果为:

main begin

displayStar begin

**********************

displayStar end

main end

 

程序执行过程如下图所示:

程序执行过程

根据图示,结合程序运行结果,大家可以分析一下程序的执行过程。在这个例子的基础上,我们再看一个有参数的例子,改写上面代码如下:

def displayStar(n):

    for i in range(n):

        print("**********************")

 

def main():

    row=int(input("行数:"))

    displayStar(row)

 

main()

 

运行程序结果为:

行数:4

**********************

**********************

**********************

**********************

 

程序实现了通过获取输入行值,输出相应行数的星号。

清楚了上面的例子,我们再看一个函数例子,编程实现求指定区间的所有整数的和。如指定1-10,则计算出1+2+3+……+10的和。自己先试着编写一下代码然后再往下看吧。

 

哎呀,我不会写呀!没有关系,不用函数会做不?不就是计算累加和吗,不难,如下:

s=0

x,y =eval(input("区间:"))

for i in range(x,y+1):

    s=s+i

print(s)

 

好下面我们需要把它改成函数方式实现。先定义函数:def关键字,函数名,括号冒号都会写

def n1n2Sum(n1,n2):  #函数名n1n2Sum求表示n1、n2之间的和。

函数头搞定,下面看函数体。函数体不就是已知n1、n2,计算n1、n2之间所有整数的和。参考上面的编写代码如下

s=0                #这个千万不要忘了

for i in range(n1,n2+1):

    s=s+i

print(s)

所以函数定义完了,下面这样,其实我就是从上复制过来的,但是要注意缩进:

def n1n2Sum(n1,n2):  #函数名表示n1、n2之间的和。

s=0                #这个千万不要忘了

for i in range(n1,n2+1):

    s=s+i

print(s)

接下来定义main函数,在main里调用上面的函数(当然可以不定义main函数,但是定义main函数程序的可读性好,代码规范)。函数调用的时候确保参数有确定值,所以需要通过input函数获取用户输入。当然可以直接指定一个值,如n1n2Sum(1,10),但是程序运行就只能计算1-10的整数和,不灵活,不方便。

def main():

    x, y = eval(input("区间:"))

    n1n2Sum(x,y)       #调用函数n1n2Sum

程序中调用main函数,简单:main()

Over,如果不熟练的话,请再练习n遍,(n>=3),送你编程秘籍:无他,唯手熟尔!

我们再看看刚才的代码:

def n1n2Sum(n1,n2):

    s=0

    for i in range(n1,n2+1):

        s=s+i

    print(s)

 

def main():

    x, y = eval(input("区间:"))

    n1n2Sum(x,y)

 

main()

 

假设我的要求改了(开发软件过程中,用户需求就是会变来变去的,所以用户需求变更位于惹毛程序员的十件事前列),我想输出的2倍,简单,函数n1n2Sum 的print(s)改成print(2*s)不就行啦。是的,可以但是代码质量不高,一般一个函数只完成一个功能,所以更好的方法是我们把函数定义成有返回值的,这样保证函数的功能就是求指定区间所有整数的和。所以代码改成下面这样的:

def n1n2Sum(n1,n2):

    s=0

    for i in range(n1,n2+1):

        s=s+i

    return s

 

def main():

    x, y = eval(input("区间:"))

    s=n1n2Sum(x,y)

    print(2*s)

 

main()

 

我们看一下n1n2Sum(n1,n2)函数的功能,实现n1-n2之间所有整数的和。可以这样理解,对于这个问题,已知两个整数n1,n2,求这两个数之间所有整数的和。已知一般可以作为函数参数,求的结果可以作为返回值,函数体是具体的功能。所以使用函数编程时,要考虑已知(作为函数的参数)和求的结果(作为函数返回值)这两部分,然后具体问题具体分析,再完成函数体部分。

我们再来一个例子:求两个整数的最大公约数和最小公倍数,最大公约数使用数学家的算法,最小公倍数使用普通人的办法。先看最大公约数的算法:

第 1 步:比较 A 和 B 这两个数,将 A 设置为较大的数,B 为较小的数。

第 2 步:A 除以 B,得余数 R(Remainder)。

第 3 步:如果 R=0,则最大公约数就是 B;否则将 B 赋值给 A,R赋值给 B,重复进行前两步。

按照上述算法,定义函数gcd,已知为                ,求的是             。所以gcd函数的参数为两个整数a,b,返回值为a,b的最大公约数。函数体呢?参见上述算法描述呀!

第 1 步:比较 A 和 B 这两个数,将 A 设置为较大的数,B 为较小的数。

对应的Python表示为:                                       

第 2 步:A 除以 B,得余数 R(Remainder)。

对应的Python表示为:                                       

第 3 步:如果 R=0,则最大公约数就是 B;否则将 B 赋值给 A,R赋值给 B,重复进行前两步。

对应的Python表示为:                                       

实际上,最后一步需要认真思考:①要使用循环实现而不是选择操作,因为有重复进行 ②什么情况下执行循环,或者说循环条件怎么写。否则应该表达为R!=0。提示到此结束,编程吧,少年!

def gcd( a , b ):

    #第 1 步:比较 A 和 B 这两个数,将 A 设置为较大的数,B 为较小的数。

    if a<b:

        a,b=b,a

    #第2步:A 除以 B,得余数 R(Remainder)。

    r= a % b

    #第3步:如果R=0,则最大公约数就是 B;否则将 B 赋值给 A,R赋值给 B,重复进行前两步。

    while r != 0:

        a = b

        b = r

        r = a % b

    return b

 

def main():

    x, y = eval(input("x,y:"))

    print(gcd(x,y))

 

main()

 

求最小公倍数就是普通人的思维方法。首先明确一点,两个数的最小公倍数值最大的可能是这两个数的乘积(似乎有点绕,我居然没有把自己绕进去,厉害了哈),我们需要让一个循环变量从这两个数中的(大值,小值)开始向这两个数的乘积方向依次加1试一下这个循环变量是否能够整除这两个数(自己思考并且圈一下前面括号里的答案),一直找到满足能够整除这两个数的为止(为止就是结束,结束在循环里就是break),这时这个就是这两个数的最小公倍数,我需要回去推敲一下前面写的对不对(大体思路是对的,修改了一下措辞)。实际上求最大公约数也可以使用类似的方法,因为我们都是普通人,暂时不能想出数学家提供的方法,反正我真想不出来。试着把上面求最小公倍数的方法修改一下,改成求最大公约数。还是先编程做完最小公倍数,然后再考虑下一个最大公约数问题吧。好啦,编程去喽!

 

def lcm( a , b ):

    xb=a*b    #思考一下这行的意义何在

    if a<b:

        a,b=b,a

    for i in range(a,a*b+1):

        if i % a == 0 and i % b == 0:

            xb = i

            break

    return xb

 

def main():

    x, y = eval(input("x,y:"))

    print(lcm(x,y))

 

main()

 

#思考一下这行的意义何在

这个问题如果自己理解不了,上课时来问我吧!

接下来我们改上面的方法求最大公约数。

两个数的最小公倍(此处改成  大公约   )数值最(此处改成        )的可能是这两个数的乘积(此处改成            ),我们需要让一个循环变量从这两个数中的(大值,小值)开始向1方向依次减1试一下这两个数是否能够整除这个循环变量(自己思考并且圈一下前面括号里的答案),一直找到满足能够整除这个循环变量的数为止(为止就是结束,结束在循环里就是break),这时这个数就是这两个数的最大公约数。好啦,编程去喽!

def gcd( a , b ):

    dy=1    #思考一下这行的意义何在

    if a<b:

        a,b=b,a

    for i in range(b,0,-1):

        if a % i == 0 and b % i == 0:

            dy = i

            break

    return dy

 

def main():

    x, y = eval(input("x,y:"))

    print(gcd(x,y))

 

main()

 

实际上,我还真有一个捷径,悄悄告诉你:两个数的乘积等于这两个数的最大公约数和最小公倍数的乘积。这个有用吗?当然了,如果写好了求最大公约数的函数gcd(x,y), 那么lcm(x,y)=x*y/ gcd(x,y)。


第八章 函数-1的评论 (共 条)

分享到微博请遵守国家法律