《Visual Basic.NET程序设计课件 第5章 过程.ppt》由会员分享,可在线阅读,更多相关《Visual Basic.NET程序设计课件 第5章 过程.ppt(78页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第 5 章 过 程,5.1 VB.NET应用程序的构成 5.2 过程的定义与调用 5.3 参数传递 5.4 数组、结构和集合参数 5.5 过程与变量的作用域 5.6 递归,一个VB.NET应用程序由各种类型的文件构成,其中包含重要的模块文件。 通常把存储子过程和函数过程的代码文件称为模块文件,并以.vb作为文件扩展名。 例如: Module1.vb 过程是程序设计语言中的一个重要概念,它是功能的抽象,是构造应用程序的基本组件。 过程有两个重要作用: 一是任务划分,即把一个复杂任务划分为若干个小任务,每个小任务用过程编写,这样做便于分工和处理,也便于验证程序的正确性; 二是软件重用,即把一些功能
2、相同或相近的程序段,独立编写成过程,让应用程序随时调用,而不需要编写雷同的代码。,5.1 VB.NET应用程序的构成,VB.NET的应用程序称为“项目”。 一个项目中的代码功能可以很丰富,很复杂。 为了便于组织和管理项目代码,.NET框架按代码性质划分为不同的“项”,并提供了不同项类型的文件框架。 单击集成开发环境中“项目”菜单项,弹出子菜单:,对于窗体、控件和组件项,系统提供可视化的编辑环境,而模块项和类项则提供代码框架和编辑环境,让用户输入代码。 这些项存放在以.vb为扩展名的模块文件中。,打开“添加新项”对话框,可以从模板中选择不同的添加项。,在这一章讨论的主要是用户自定义子过程和函数过
3、程,它们都是写在“模块”项中的代码,在该模块中可以直接调用。 VB.NET项目可以包含多个模块文件。 模块文件的默认文件名是Modulei.vb ,其中i=1 , 2 , 。 自定义的子过程和函数过程也可以提供给应用程序中其他.vb模块文件调用。 模块文件名可以由用户修改,但不应该修改.vb扩展名,否则,系统无法识别。,过程是完成特定功能的一组程序代码,这组程序代码是由若干个语句构成的。,5.2 过程的定义与调用,VB.NET的过程有两大类。 一类由系统提供,包括内部函数和事件过程。对于事件过程,VB.NET提供它们的框架和接口,用户可以根据需要填写内容。 另一类是用户根据需要自己定义的过程。
4、 在VB.NET中,有下列5种自定义过程: 以关键字Sub开头的子过程; 以关键字Function开头的函数过程; 以关键字Property开头的属性过程; 以关键字Event开头的事件过程; 运算符过程。,自定义过程可以由用户在模块代码编辑环境中输入代码。 单击鼠标右键,弹出的快捷菜单:,选择“插入代码段”,出现“插入代码段”子菜单。,选择“代码模式”,系统会自动生成用户所需要的代码框架,让用户填入代码。,5.2.1 Sub过程的定义与调用,用户自定义的Sub过程是用特定格式组织起来的一组代码,通常用来完成某一个特定功能。,要使用用户自定义Sub过程来编写程序时要做两种事情: 一是要定义Su
5、b过程; 二是要调用Sub过程。,1. Sub过程的定义,定义格式: Private|Public Static Sub () Exit Sub End Sub 其中: 过程的第一行称为过程首部。Sub是定义过程的关键字。前缀Private、Public、Static为可选关键字,用以说明过程的性质,默认为Public。 :用户自定义的过程名。 :以括号括起来的形式参数表,各参数之间用逗号分隔。形式参数表为空时,也需要使用圆括号。 最后一行End Sub是过程结束语句。过程首部与End Sub之间的语句称为过程体。 过程体内可以用Exit Sub语句强制结束过程的执行。,过程体:由完成过程功能
6、的一系列语句构成。,例5-1,定义无形式参数的Sub过程。,Sub Simple1() WriteLine(A simplest procedure!) End Sub,过程体,例5-2,打印一个用符号组成的直角三角形图案。,Private Sub triangle(ByVal str As String, ByVal n As Integer) Dim i As Integer, j As Integer For i = 1 To n For j = 1 To i Write(str) Next j WriteLine() Next i End Sub,过程首部,过程体,结束语句,Publi
7、c Sub fact(Byval n As Integer,Byref fac As Long) Dim t As Long,i As Integer t=1 For i=1 To n t=t*i Next i fac=t End Sub,补充例:求n! 有参子过程。,过程首部,结束语句,过程体,2. Sub过程的调用,调用子过程语句的格式有两种: 第一种格式: ( ) 第二种格式: call () 其中 为已定义子过程的名字。 为实际参数表,实际参数一般为常数、常量、变量和数组等,也可以为表达式。 实际参数必须在数目、类型和排列次序与相应SUB过程定义的形式参数表中的参数一致。,说明: 实际
8、参数表为可选项,缺省时调用的是无参过程。,当执行程序执行到子过程调用语句调用无参过程时,vb系统转去执行子过程体中的语句。 执行之后就转回刚调用子过程语句的下一个语句去执行。,例如:Call simple1 或 simple1,当执行程序执行到子过程调用语句调用有参过程时,vb系统先进行参数的传送,然后执行子过程体中的语句。 执行之后就转回刚调用子过程语句的下一个语句去执行。,又如:Call triangle(“*”,5) 或 triangle (“*”,5),Sub Simple1() WriteLine(A simplest procedure!) End Sub,Private Sub
9、triangle(ByVal str As String, ByVal n As Integer) Dim i As Integer, j As Integer For i = 1 To n For j = 1 To i Write(str) Next j WriteLine() Next i End Sub,例5-3,调用例5-2定义的过程。,Imports System.Console Module Module1 Sub Main() Dim Chx As String, Num As Integer Chx = * Num = 8 Call triangle(Chx, Num) 使用C
10、all关键字的调用格式 Chx = $ triangle(Chx, Num / 2) 不用Call关键字的调用格式 End Sub Private Sub triangle(ByVal str As String, ByVal n As Integer) Dim i As Integer, j As Integer For i = 1 To n For j = 1 To i Write(str) Next j WriteLine() Next i End Sub End Module,* * * * * * * *,$ $ $ $ $ $ $ $ $ $,运行程序,当在程序中需要多次用到某一公
11、式或要处理某一函数关系,而又没有现成的内部函数可以使用时,用户自己可以定义一些函数来使用。,自己定义的函数通常称为Function过程。,Function过程也是用特定格式组织起来的一组代码。 Function过程在调用结束时带回一个值,该值称为Function过程的返回值。这个值的类型称为Function过程的类型。,要使用自己定义的函数过程来编程序需要做两件事: 一是要定义Function过程; 二是要调用Function过程。,5.2.2 Function过程的定义和调用,1. Function 过程的定义,定义格式: Public|PrivateStaticFunction()As =
12、 Exit Function = | Return End Function 第一行称为函数过程首部。 Function是定义函数的关键字。Private、Public、Static为可选关键字,意义同上。 函数有返回值,由As 指明返回值的数据类型。 Function与End Function之间的语句称为函数体。 函数体中应该至少有一个返回函数值的语句。 函数值返回语句有两种形式:向函数名赋予表达式的值和通过Return语句返回表达式的值。 若函数没有返回值语句,则函数返回一个默认值。 数值型函数的默认值为0,字符串型函数的默认值为空串。,例如,求三个数的最大值可以定义一个函数过程:,Pr
13、ivate Function max( ByVal x As Single, ByVal y As Single, _ ByVal z As Single) As Single Dim m As Single If xy Then m=x Else m=y If zm Then m=z max=m End Function,Return m,Public Function fact(ByVal n As Integer) As Long Dim i As Integer, t As Long t=1 For i=1 To n t=t*i Next t fact=t End Function,又
14、如,求阶乘也可以定义一个函数过程:,Return t,要使用函数过程必须调用它,而调用函数过程的常用格式为: 函数过程名(实际参数表) 其中函数过程名用标识符表示。实际参数表中的参数一般为常数、常量、变量等,更一般为表达式,它们必须在数目、类型和排列次序上与相应函数过程定义的形式参数表中参数一致。,函数过程一般在表达式中调用。当系统在执行程序遇到函数过程调用时,先进行参数传送,然后执行函数过程体中的语句,并通过函数名把函数值带回表达式进行运算。,例如:y=max(0.75,100,85.5),2.函数过程的调用,Private Function max( ByVal x As Single,
15、ByVal y _ As Single,ByVal z As Single) As Single Dim m As Single If xy Then m=x Else m=y If zm Then m=z max=m End Function,s=(fact(5)+fact(7)/fact(8),Public Function fact(ByVal n As Integer)As Long Dim i As Integer,t As Long t=1 For i=1 To n t=t*i Next t fact=t End Function,例5-4,使用函数计算圆面积。,Imports S
16、ystem.Console Module Module1 Function area(ByVal radius As Double) As Double area = 3.14159 * radius * radius End Function Sub Main() Dim r#, a# Write(请输入半径:) r = Val(ReadLine() a = area(r) 调用函数,计算圆面积 WriteLine(半径 = 0, 面积 = 1, r, a) End Sub End Module,Return 3.14159* radius * radius,运行程序,例5-5,把一个百分制
17、成绩转换为五级分数段的字符串形式。,Imports System.Console Module Module1 Function Passed(ByVal score%) As String Select Case score Case 0 To 59 Passed = 不及格” 或者 Return 不及格 Case 60 To 69 Passed = 及格或者 Return 及格 Case 70 To 79 Passed = 中等或者 Return 中等 Case 80 To 89 Passed = 良好或者 Return 良好 Case 90 To 100 Passed = 优秀或者 Re
18、turn 优秀 Case Else Passed = 数据错!或者 Return 数据错! End Select End Function,Sub Main() Dim score% = 0 Do Until score = -1 Write(请输入成绩(-1结束):) score = Val(ReadLine() If score -1 Then WriteLine(Passed(score) End If Loop End Sub End Module,运行程序,当调用子过程或函数过程时,先要进行参数的传递。具体一点讲,调用过程时要把需处理的原始数据传送给形式参数。 另外,执行过程中的语句
19、之后的计算或处理结果也需要传递回调用程序。 在这一节要介绍如何把需处理的原始数据传递给过程和如何把执行过程体后的结果传递回调用程序。,5.3 参数传递,过程的参数传递有两种方式: 一种是值传递方式,过程的形式参数称为传值参数,采用这种方式的调用称为传值调用; 另一种是地址传递方式,过程的形式参数称为引用参数,采用这种方式的调用称为传址调用。,7.3.1 形式参数和实际参数,如果在过程定义中,形式参数前使用关键字ByVal,则该参数称为数值参数或传值参数。 过程调用时的参数传递过程:系统先开辟形式参数的临时存储空间,并把实际参数的值传递给或者说赋给对应的形式参数。 执行过程体时,对形式参数进行的
20、任何操作与实际参数没有任何联系。 过程执行完毕,系统收回形式参数的临时存储空间 。,5.3.2 传值参数,例5-6,传值参数测试。,Imports System.Console Module Module1 Sub Main() Dim x%, y% x = 5 y = 10 WriteLine( x=0, y=1, x, y) WriteLine() NoChange(x, y) WriteLine( x=0, y=1, x, y) WriteLine() End Sub,Sub NoChange(ByVal a%, ByVal b%) a = a + b b = a * b WriteLi
21、ne( a=0, b=1, a, b) WriteLine() End Sub End Module,运行程序,5.3.3 可选参数,在过程定义中可以指定传值的形式参数为可选参数,调用过程时不必为可选参数提供实际参数。 1定义可选参数 可选参数由关键字Optional开始。具有可选参数的过程首部语法形式: Sub| Function (ByVal As , _ Optional ByVal As = ,) 说明: 过程定义中必须为每个可选参数指定默认值。 可选参数的默认值必须是一个常数表达式。 过程定义中跟在可选参数后的每个参数也都必须是可选的。 例如,以下函数过程首部定义了两个可选参数: F
22、unction distance(ByVal x1 As Double, ByVal y1 As Double, _ Optional ByVal x2 As Double=0,Optional ByVal y2 As Double=0),2调用带可选参数的过程 调用带可选参数的过程时,可以选择是否提供对应的实际参数。 如果不提供实际参数,过程将使用参数声明的默认值。 当省略参数列表中的一个或多个可选参数时,使用连续的逗号来标记它们的位置。 例如:,D1=distance(x1, y1, , y2) 省略第三个参数 D2=distance(x1, y1, x2) 省略第四个参数,例5-7,定义
23、并调用函数,求两个坐标点之间的距离。,Imports System.Console Imports System.Math Module Module1 Sub Main() Dim x1#, y1#, x2#, y2# x1 = 3 : y1 = 4 : x2 = 5 : y2 = 7 WriteLine(The distance of (0,1) t0 (2,3) : 4:f3, _ x1, y1, x2, y2, distance(x1, y1, x2, y2) WriteLine(The distance of (0,1) t0 (0,0) : 2:f3, _ x1, y1, dist
24、ance(x1, y1) WriteLine(The distance of (0,1) t0 (0,2) : 3:f3, _ x1, y1, y2, distance(x1, y1, , y2) WriteLine(The distance of (0,1) t0 (2,0) : 3:f3, _ x1, y1, x2, distance(x1, y1, x2) End Sub,Function distance(ByVal x1 As Double, ByVal y1 As Double, Optional ByVal x2 As Double = 0, Optional _ ByVal y
25、2 As Double = 0) As Double Return Sqrt(x1-x2) 2 + (y1-y2) 2) End Function End Module,运行程序,如果在过程定义中,形式参数前使用关键字ByRef或无关键字,则该参数称为引用参数或传址参数。 调用过程时,形式参数存放实际参数的地址,过程体中通过间址方式访问实际参数值。 过程调用时的参数传递过程:系统先开辟形式参数的临时存储空间,并把实际参数的地址赋给对应的形式参数。 执行过程体时,对形式参数的任何操作实际上是通过间址操作对实际参数进行。 过程执行完毕,系统收回形式参数的临时存储空间 。,5.3.4 引用参数,例5
26、-8,引用参数测试。,Imports System.Console Module Module1 Sub Main() Dim x%, y% x = 5 y = 10 WriteLine( x=0, y=1, x, y) WriteLine() IsChange(x, y) WriteLine( x=0, y=1, x, y) WriteLine() End Sub,Sub IsChange(ByRef a%, ByRef b%) a = a + b b = a * b WriteLine( a=0, b=1, a, b) WriteLine() End Sub End Module,运行程序
27、,5.3.5 关于参数的讨论,从语法上,不论是Sub过程还是Function过程,它们都是程序功能模块,同一个问题,既可以写成Sub过程,也可以写成Function过程。 在实际应用中,应该注意传值参数和引用参数的使用。 传值调用过程时,传值参数把实际参数的值传(赋)给形式参数作为初值。 当形式参数为变量名时,过程体内对形式参数的修改不会影响相应实际参数。 因此,当需要保护实际参数使其不被外部修改时,应采用传值参数。,一般来说,引用参数对应的实际参数为类型相同的变量名。 传址调用执行过程体时,对形式参数的操作是通过间址方式对实际参数进行。 这种传址方式既可以读取实际参数调用过程时的初值,也可以
28、利用函数体中的代码修改实际参数的值。 因此,当程序需要在执行过程体中通过形式参数修改实际参数时,应该选择引用参数。 或者说当程序需要在执行过程体中返回一个或多个结果时,应该选择引用参数。,Public Sub fact(Byval n As Integer,Byref fac As Long) Dim t As Long,i As Integer t=1 For i=1 To n t=t*i Next i fac=t End Sub,Public Function fact(ByVal n As Integer) As Long Dim i As Integer, t As Long t=1
29、For i=1 To n t=t*i Next t fact=t End Function,Return t,用子过程和函数过程求n!的比较,S=(fact(5)+fact(7)/fact(8),Call fact(5,f1) Call fact(7,f2) Call fact(8,f3) S=(f1+f2)/f3,例5-9,计算存款一年后所得总款项。,Imports System.Console Module Module1 Sub Main() Const highRate As Double = 12.5 用常量定义高利率 Dim lowRate = highRate * 0.6 变量,
30、赋低利率值 Dim initialDebt = 4999.99 原始款项 WriteLine(原始款项: 0:c, initialDebt) Dim debtWithInterest = initialDebt含利率款项,初值为 原始款项 Calculate(highRate, debtWithInterest) WriteLine(高利率计算所得款项: 0:c, debtWithInterest) 重置原始款项值 debtWithInterest = initialDebt Calculate(lowRate, debtWithInterest) WriteLine(低利率计算所得款项: 0
31、:c, debtWithInterest) End Sub,Sub Calculate(ByVal rate As Double, ByRef debt As Double) debt = debt + (debt * rate / 100) End Sub End Module,运行程序,说明:若引用参数对应的实际参数为常数或表达式,则此时参数的传递效果就如同传值参数一样。 例如,对例5-8,把Main过程中调用IsChange过程的语句改为: IsChange(x + 3, y) 程序仍可以正常运行,形式参数接收了表达式x+3的值,过程中对形式参数a的修改不影响实际参数x。,Imports
32、 System.Console Module Module1 Sub Main() Dim x%, y% x = 5 y = 10 WriteLine( x=0, y=1, x, y) WriteLine() IsChange(x+3, y) WriteLine( x=0, y=1, x, y) WriteLine() End Sub,Sub IsChange(ByRef a%, ByRef b%) a = a + b b = a * b WriteLine( a=0, b=1, a, b) WriteLine() End Sub End Module,数组、结构和集合都可以作为过程定义中的参
33、数。,5.4 数组、结构和集合参数,1. 数组元素作为参数,5.4.1 数组参数,数组作为过程参数有两种情形:数组元素作为过程参数; 整个数组作为过程参数。,Imports System.Console Module Module1 Sub Main() Dim a(2) As Integer, i As Integer For i = 0 To 2 a(i) = i + 1 Next For i = 0 To 2 Write(a(0)=1 , i, a(i) Next WriteLine(),例5-10,测试数组元素作为过程参数。,WriteLine(Call ByVal:) Call Fu
34、nAry1(a(0), a(2) For i = 0 To 2 Write(a(0)=1 , i, a(i) Next WriteLine() WriteLine(Call ByRef:) Call FunAry2(a(0), a(2) For i = 0 To 2 Write(a(0)=1 , i, a(i) Next WriteLine() End Sub,Public Sub FunAry1(ByVal x%, ByVal y%) x = x + 1 y = y + 1 WriteLine(“FunAry1: x=0 y=1”, x, y) End Sub Public Sub FunA
35、ry2(ByRef x%, ByRef y%) x = x + 1 y = y + 1 WriteLine(FunAry2: x=0 y=1, x, y) End Sub End Module,运行程序,2数组整体作为参数,以数组作为过程的形式参数时,按传址方式传递。 VB.NET要向形式参数传送实参数组的首地址,把整个数组传递给过程进行处理, 即是处理实参数组。 在定义过程时,形式参数表中的数组用数组名后面添加一对圆括号表示: ByRef ( ,) As 其中,逗号用于表示多维数组。 n维数组有n-1个逗号。 说明: 在VB.NET中,使用ByVal也可声明数组参数,也是按传址方式传递。 在
36、过程调用时,实际参数表中的数组无论是多少维数组,数组名都表示实参数组的地址。,例5-11,定义一个过程,循环移动数组元素。对数组A,移动的方法是把A(i+1)移到第i个位置,第一个元素移到最后一个位置。,Imports System.Console Module Module1 Sub MoveAry(ByRef A( ) As Integer) Dim U%, j%, Tmp% U=UBound(A) 取数组上界 If U= 0 Then Exit Sub检查数组元素 Tmp=A(0) 保存第1个元素 For j = 1 To U 从第2个元素开始,后一个元素冲掉前一个元素 A(j-1)=A
37、(j) Next j A(U )=Tmp 最后一个元素换成原来的第1个元素 End Sub,对形式参数数组A的任何操作实际上是对实际参数数组进行。,Sub Main() Dim j% Const N =5 Dim B(N) As Integer For j = 0 To N 数组赋初值 B(j) = j + 1 Next WriteLine(移动前的数组:) For j = 0 To N 显示原始数组 Write(0 , B(j) Next j WriteLine() Call MoveAry(B) 调用过程,移动数组元素 WriteLine(移动后的数组:) For j = 0 To N 显
38、示移动后的数组 Write(0 , B(j) Next j WriteLine() End Sub End Module,Sub MoveAry(ByRef A( ) As Integer) Dim U%, j%, Tmp% U=UBound(A) 取数组上界 If U= 0 Then Exit Sub检查数组元素 Tmp=A(0) 保存第1个元素 For j = 1 To U 从第2个元素开始,后一个元素冲掉前一个元素 A(j-1)=A(j) Next j A(U )=Tmp 最后一个元素换成原来的第1个元素 End Sub,Sub Main() Dim j% Const N =5 Dim
39、B(N) As Integer For j = 0 To N 数组赋初值 B(j) = j + 1 Next WriteLine(移动前的数组:) For j = 0 To N 显示原始数组 Write(0 , B(j) Next j WriteLine() Call MoveAry(B) 调用过程,移动数组元素 WriteLine(移动后的数组:) For j = 0 To N 显示移动后的数组 Write(0 , B(j) Next j WriteLine() End Sub End Module,Sub MoveAry(ByRef A( ) As Integer) Dim U%, j%,
40、 Tmp% U=Ubound(B) 取数组上界 If U= 0 Then Exit Sub检查数组元素 Tmp=B(0) 保存第1个元素 For j = 1 To U 从第2个元素开始,后一个元素冲掉前一个元素 B(j-1)=B(j) Next j B(U )=Tmp 最后一个元素换成原来的第1个元素 End Sub,运行程序,例5-12,计算方阵对角元素的和。,Imports System.Console Module Module1 Function trace(ByRef ary(,) As Integer) As Integer Dim i%, s% s = 0 For i = 0 T
41、o UBound(ary) s = s + ary(i, i) Next i trace = s End Function,Sub Main() Const N% = 49 Dim i As Integer, j As Integer, B(N, N) As Integer Randomize() For i = 0 To N For j = 0 To N B(i, j) = Int(Rnd() * 100) Next j Next i WriteLine(Sum = 0, trace(B) End Sub End Module,Function trace(ByRef ary(,) As I
42、nteger) As Integer Dim i%, s% s = 0 For i = 0 To Ubound(B) s = s + B(i, i) Next i trace = s End Function,例5-12,计算方阵对角元素的和。,Imports System.Console Module Module1 Function trace(ByRef ary(,) As Integer) As Integer Dim i%, s% s = 0 For i = 0 To UBound(ary) s = s + ary(i, i) Next i trace = s End Functio
43、n,Sub Main() Const N% = 49 Dim i As Integer, j As Integer, B(N, N) As Integer Randomize() For i = 0 To N For j = 0 To N B(i, j) = Int(Rnd() * 100) Next j Next i WriteLine(Sum = 0, trace(B) End Sub End Module,Function trace(ByRef ary(,) As Integer) As Integer Dim i%, s% s = 0 For i = 0 To Ubound(B) s
44、 = s + B(i, i) Next i trace = s End Function,运行程序,5.4.2 结构参数,结构变量可以作为过程参数。因为结构是值类型,既可以使用传值参数, 也可以使用引用参数。 过程参数既可以是结构的元素,也可以是结构变量。,例5-13,测试结构参数。,Public Structure point Public x As Integer Public y As Integer End Structure Imports System.Console Module Module1 Private Sub MovePoint(ByRef p As point) p.
45、x = p.x + 10 p.y = p.y + 10 End Sub,Sub Main() Dim pp As point pp.x = 200 pp.y = 100 WriteLine( Point1 (0,1), pp.x, pp.y) MovePoint(pp) WriteLine( Point2 (0,1), pp.x, pp.y) End Sub End Module,运行程序,例5-14,在一个结构数组中插入一个新结构元素。,Imports System.Console Module Module1 在第i个位置插入 Sub insert(ByRef A() As stu, By
46、Ref term As stu, ByVal i As Integer) Dim L%, H%, j% H = UBound(A) If i H Then i = H 若i大于数组长度,则添加于尾 ReDim Preserve A(H + 1) 数组重定义,增加一个元素 For j = H To i Step-1 后移元素,空出第i个位置 A(j).name = A(j-1).name A(j).score = A(j-1).score Next j A(i-1).name = term.name把结构插入第i个位置 A(i-1).score = term.score End Sub,Structure stu Public name As String Public score As Single End Structure,Sub Main() Const N = 5 Dim b(N) As stu Dim InsTerm As stu, j% b(0).name = 陈一 : b(0).score = 72.5 数组置初值 b(1).name = 何二 : b(1).score = 83.1 b(2).name = 张三 : b(2).score = 65.5 b(3).name =