1 / 41

第 6 章 学习编写结构化的程序 —— 过程

第 6 章 学习编写结构化的程序 —— 过程. 实际应用中的大部分应用软件都很庞大,需要多个人共同合作完成程序的编写。将所有代码都写在一起,不仅不利于多人合作,也不便于修改和维护。经验表明,要开发和维护一个大的应用程序,最好的方法就是分而治之( divide and conquer ),即将大的应用程序分解为小的彼此之间相对独立的程序块,这称为结构化编程的程序设计方法。使用这种方法可以很大程度地简化大型应用程序的设计、开发和维护。 本章我们就来介绍 VB.NET 中的两种类型的通用过程,即 Sub 子过程和 Function 函数过程。. 章节内容. 6.1 什么是过程

gaia
Télécharger la présentation

第 6 章 学习编写结构化的程序 —— 过程

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第6章 学习编写结构化的程序——过程 实际应用中的大部分应用软件都很庞大,需要多个人共同合作完成程序的编写。将所有代码都写在一起,不仅不利于多人合作,也不便于修改和维护。经验表明,要开发和维护一个大的应用程序,最好的方法就是分而治之(divide and conquer),即将大的应用程序分解为小的彼此之间相对独立的程序块,这称为结构化编程的程序设计方法。使用这种方法可以很大程度地简化大型应用程序的设计、开发和维护。 本章我们就来介绍VB.NET中的两种类型的通用过程,即Sub子过程和Function函数过程。

  2. 章节内容 • 6.1 什么是过程 • 6.2 Sub子过程 • 6.3 Function函数过程 • 6.4 为过程传递参数

  3. 6.1 什么是过程 • 过程是一条或多条语句组成的语句块,通常按照逻辑组织起来,能够完成一定的任务。 • VB.NET中的过程主要有Sub子过程和Function函数过程两种。 • 一般来说,应用程序中的每行代码都处于某个过程中,如Main、Button1_Click等。

  4. 为什么要使用过程 • 可以提高程序的可读性。 • 过程代码可以重用。一个过程在创建之后,可以在程序的任何一个地方调用。 • 使得应用程序更容易调试、修改和维护。 • 更便于多人协同合作开发。

  5. 过程访问修饰符 • Public:被该修饰符修饰的过程称为公共过程,可以在应用程序的任何地方被访问。 • Private:被该修饰符修饰的过程称为私有过程,仅能由声明该过程的类或者模块访问。 • Shared:被该修饰符修饰的过程称为共享过程,不与声明该过程的类的实例相关联,可以通过类名来直接访问。

  6. 过程访问修饰符 • Protected:被该修饰符修饰的过程称为受保护过程,仅能由声明该过程的类及其派生类访问。 • Friend:被该修饰符修饰的过程称为友元过程,可以由包含该过程声明的应用程序中的任何类或者模块中访问。 • Protected Friend:被该修饰符修饰的过程称为受保护的友元过程,可以从同一程序集、声明该过程的类及其派生类中访问。

  7. 6.2 Sub子过程 • Sub子过程由关键字Sub开头,End Sub结尾,其语法格式如下。 • 访问修饰符 Sub 子过程名([参数列表]) • 过程体 • End Sub

  8. [子过程名]是将要创建的子过程的名称,其命名规则同变量命名规则,采用字母和下划线开头,由字母、数字和下划线组成。[子过程名]是将要创建的子过程的名称,其命名规则同变量命名规则,采用字母和下划线开头,由字母、数字和下划线组成。 • [参数列表]是在子过程中使用的参数,个数可以是0个或者多个。该项可选,如果不止一个参数,则使用逗号分开。参数的传递有传值和引用两种,详见6.4节。 • 过程体则是组成该过程的语句集合。

  9. 示例1:通过“Greeting”程序学习如何创建和使用Sub子过程示例1:通过“Greeting”程序学习如何创建和使用Sub子过程 • Step1:新建VB.NET项目,单击菜单栏中的【文件】→【新建项目】命令,在【模板】列表框中选择【Windows窗体应用程序】,在【名称】文本框中输入“Greeting”。 • Step2:进行窗体界面设计。

  10. Step3:创建Greeting子过程。 1 Sub Greeting(ByVal name As String) 2 Dim msg As String 3 If name <> "" Then 4 msg = "Glad to meet you," & name & "!" 5 Else 6 msg = "You haven't tell me your name yet!" 7 End If 8 MsgBox(msg, 0, "Best Wishes!") 9 End Sub

  11. Step4:调用过程Greeting。 1 Private Sub btn_OK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_OK.Click 2 Greeting(tb_name.Text) 3 End Sub

  12. 小结 • 过程定义包含过程头、过程体和End Sub关键字。 • 过程头由Sub关键字开始,后跟过程名,之后是一对圆括号括起来的形参列表。 • 形参列表中包含对形参变量的声明。如果有多个参数,则用逗号分割。

  13. 小结 • 过程调用采用“过程名(实参列表)”的形式。对于过程头形参列表中每一个形参来说,调用时都必须有一个实参与之相对应,二者类型必须一致,即实参的值能够赋值给相应的形参变量。当然,实参也可以是常量或者表达式,只要类型与形参一致即可。

  14. 6.3 Function函数过程 • Function函数过程简称函数,由关键字Function开头,End Function结尾,其基本结构如下。 • Function 函数名([参数列表]) As 返回值类型 • 函数体 • End Function

  15. Function与Sub的不同 • 二者唯一不同的地方在于,Function函数的参数列表之后比Sub子过程多了一项As 返回值类型。 • 这是因为,Function函数允许函数体运行结束后,向调用过程返回一个结果,称为返回值,其类型由As 返回值类型来定义。Function函数有且仅有一个返回值。

  16. 示例1:通过阶乘计算程序来学习Function函数过程的创建和使用示例1:通过阶乘计算程序来学习Function函数过程的创建和使用 • Step1:新建VB.NET项目,选择Windows窗体应用程序,并命名为FactorialCalculator。 • Step2:窗体设计。

  17. Step3:编写用于计算阶乘的Function函数Fac。 1 Function Fac(ByVal n As Integer) As Long 2 Dim result As Long 3 result = 1 4 Do While n > 0 5 result = result * n 6 n = n-1 7 Loop 8 Fac = result 9 End Function

  18. Step4:调用Fac函数。 1 Private Sub btn_Calculate_Click(ByVal sender As System.Object,ByVal e As System.EventArgs) Handles btn_Calculate_Click 2 tb_result.Text = Fac(Val(tb_num.Text)) 3 End Sub

  19. 运行结果

  20. 小结 • 函数定义包含函数头、函数体和End Function关键字。 • 函数头由Function关键字开始,后跟函数名,之后是一对圆括号括起来的形参列表。 • 形参列表中包含对形参变量的声明。如果有多个参数,则用逗号分割。

  21. 小结 • 形参列表后面是关键字As 返回值类型,用于定义函数返回值的类型。 • 函数调用采用“变量名=函数名(实参列表)” 的形式。实参和形参也必须一一对应。与Sub子过程不一样的地方在于,由于Function函数有返回值,因此在调用时需要将该值赋值给某个变量。注意,该变量类型应该与函数返回值类型一致。

  22. 6.4 为过程传递参数 • Sub子过程和Function函数都可以有零到多个形参,在实际调用的时候需要由实参与之一一对应,这个过程就称为参数传递。

  23. 6.4.1 按值传递和按引用传递 • 通常,可以通过两种方式把实参传递给过程,即按值传递(也称为传值)和按引用传递(也称为传地址),因此参数可以分为值类型参数(以ByVal关键字标识)和引用类型参数(以ByRef关键字标识)两种。 • VB.NET中的参数默认都是ByVal类型的。

  24. 当实参按值传递时,仅仅是将实参的值赋值给形参变量。在被调用过程中,对该形参变量的修改不会影响到调用过程中实参变量的值。当实参按值传递时,仅仅是将实参的值赋值给形参变量。在被调用过程中,对该形参变量的修改不会影响到调用过程中实参变量的值。 • 与此相反,当实参按引用传递时,被调用过程可以直接访问甚至修改实参变量。

  25. 示例1:实现两个数的交换 • Swap1,参数采用按值传递 Sub Swap1(ByVal x As Short, ByVal y As Short) Dim t As Short t = x x = y y = t End Sub • Swap2,参数采用按引用传递 Sub Swap2(ByRef x As Short, ByRef y As Short) Dim t As Short t = x x = y y = t End Sub

  26. 分别调用这两个过程 a = 10 b = 20 Swap1(a, b) MessageBox.Show("a=" & a.ToString( ) & ";b=" & b.ToString( )) a = 10 b = 20 Swap1(a, b) MessageBox.Show("a=" & a.ToString( ) & ";b=" & b.ToString( )) ? X √

  27. Why? • Swap1采用的是按值传递,被调用时,实参a将值10传递给形参变量x,实参b将值20传递给形参变量y。 • 在过程内部,x和y的值进行了交换,即x值变为20,y值变为10,但是此次交换并没有影响到被调用过程中变量a和b的值。 • 因此,Swap1过程调用结束后,a和b的值没有发生变化。

  28. 而Swap2采用的是按引用传递,被调用时,实参a将变量a地址传递给形参变量x,实参b将变量b的地址传递给形参变量y。而Swap2采用的是按引用传递,被调用时,实参a将变量a地址传递给形参变量x,实参b将变量b的地址传递给形参变量y。 • 此时,变量a和变量x指向同一个内存单元,变量b和变量y指向同一个内存单元。之后在过程内部,x和y的值进行了交换。由于x和y分别指向变量a和b的内存单元,因此此次交换也同时影响到了被调用过程中变量a和b。 • 因此,Swap2过程调用结束后,a和b的值成功的进行了交换。

  29. a 10 x 10 a 10 x 两种参数传递方式的区别 • 按值传递方式,仅传递变量的值,实参变量和形参变量分别指向内存中的不同空间。 • 而按引用传递方式,传递的是变量的地址,实参变量和形参变量指向内存中的同一个空间。

  30. 几点建议 • 如果要将子过程中的运算结果返回调用过程,参数传递时应该选用传地址方式;此时实参必须是同类型的变量名,而不能是常量或表达式。 • 形参是数组、自定义类型、对象等数据时,必须使用传地址方式。 • 除此之外,通常使用传值方式,以减少被调过程和调用过程之间的关联。

  31. 6.4.2 可选参数 • 在定义过程的时候,可以指定过程的参数是可选的,即在调用该过程时,不需要为这些可选的参数提供实参与之对应。其中,可选参数由关键字Optional指明。

  32. 例子 • 下面的代码是一个计算乘积的函数Multi,其第3个参数是可选参数。 • 1 Function Multi(ByVal fir As Integer,ByVal sec As Integer,Optional ByVal third As Integer=1) As Integer • 2 Return fir*sec*third • 3 End Function

  33. 下面的代码调用Multi函数计算两个数的乘积。 • 1 Dim Result As Integer • 2 Result=Multi(10,20) • 下面的代码调用Multi函数计算三个数的乘积。 • 1 Dim Result As Integer • 2 Result=Multi(10,20,30)

  34. 6.4.3 不定量参数 • 通常,调用过程时传递的参数个数不能超出过程声明指定的数目,那么,如果在过程声明的时候参数个数并不确定,需要在调用该过程的时候才能确定参数个数,能否实现呢?比如如何实现一个能够计算多个整数乘积的Multi函数?

  35. 这样的过程我们称为可变参数过程。VB.NET对于可变参数过程的实现,采用参数数组的方式,即不单独声明每个参数,而是声明一个参数数组,允许过程接受一组值作为参数。其中参数数组使用关键字ParamArray声明。这样的过程我们称为可变参数过程。VB.NET对于可变参数过程的实现,采用参数数组的方式,即不单独声明每个参数,而是声明一个参数数组,允许过程接受一组值作为参数。其中参数数组使用关键字ParamArray声明。

  36. 下面的代码声明了一个使用参数数组的Multi函数。下面的代码声明了一个使用参数数组的Multi函数。 • 1 Function Multi(ByVal ParamArraynumbers( ) As Integer) As Integer • 2 Dim n ,x As Integer3 n = 1 • 4 For Each x In numbers • 5 n = n * x • 6 Next x • 7 Return n • 8 End Function

  37. 下面的代码调用该函数计算任意多个整数的乘积。下面的代码调用该函数计算任意多个整数的乘积。 • Dim Result As Integer • Result=Multi(2,4,6,7,,8) • 下面的代码将数组传递给参数数组。 • Dim a As Integer ( )= new Integer(5){2,3,6,7,8} • Result=Multi(a)

  38. 6.4.4 按位置传递和按名称传递 • 在调用Sub或Function过程时,可以按位置传递参数(即按照参数出现在过程定义中的顺序)或者按名称传递参数,而不考虑位置。 • 按名称传递参数时,指定参数的声明名称,后接冒号(:)和等号(=),后面是参数值。可以按照任意的顺序提供命名参数。

  39. 下面代码是一个带有三个参数的Sub过程。 • 1 Sub studentInfo(ByVal name As String, _ • 2 Optional ByVal age As Short = 0, _ • 3 Optional ByVal birth As Date = #1/1/2000#) • 4 • 5 Debug.WriteLine("Name = " & name & _ • 6 "; age = " & CStr(age) & _ • 7 "; birth date = " & CStr(birth)) • 8 End Sub

  40. 可以按位置传递参数(以逗号分隔)来调用studentInfo过程,代码如下。可以按位置传递参数(以逗号分隔)来调用studentInfo过程,代码如下。 • studentInfo("Mary", 19, #9/21/1981#) • 如果在一个按位置排列的参数列表中省略可选参数,必须用逗号保留它的位置。下面的示例调用了没有age参数的studentInfo过程。 • studentInfo("Mary", , #9/21/1981#)

  41. 另一种方法是,可以按名称传递参数(同样以逗号分隔)来调用studentInfo过程,代码如下。另一种方法是,可以按名称传递参数(同样以逗号分隔)来调用studentInfo过程,代码如下。 • studentInfo(age:=19, birth:=#9/21/1981#, name:="Mary") • 在单个过程调用中,可以同时按位置和按名称提供参数,代码如下。 • studentInfo("Mary", birth:=#9/21/1981#)

More Related