41
1 6 6 第 第第第第第第第第第第 第 第第第第第第第第第第 —— —— 第第 第第 第第第第第第第第第第第第第第第第第 第第第第第第第第第第第第第第第第第 第第第第第第 ,。 第第 第第 第第第第第第第第第第 第第第第第第第第第第 第第第第第 第第第第第第第 第第 一,,。,一 第第第第第 第第第第第第第第第第第第 ,( divide and conquer 第第 ), 第第第第第第第第第第第第第第第第第第第第第第第 第第第第第第第第第第第第第第第第 第 ,。 第第第第第第第第第第第第第第第第第第第第第第第 第第第第第第 、。 第第第第第第第第 VB.NET 第第第第第第第第第第第 Sub 第第第第 Function 第第第第

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

  • Upload
    gaia

  • View
    152

  • Download
    0

Embed Size (px)

DESCRIPTION

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

Citation preview

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

1

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

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

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

2

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

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

3

6.1 6.1 什么是过程什么是过程过程是一条或多条语句组成的语句块,通常按照逻辑组织起来,能够完成一定的任务。

VB.NET中的过程主要有 Sub子过程和 Function函数过程两种。

一般来说,应用程序中的每行代码都处于某个过程中,如Main 、 Button1_Click等。

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

4

为什么要使用过程为什么要使用过程可以提高程序的可读性。过程代码可以重用。一个过程在创建之后,可以在程序的任何一个地方调用。

使得应用程序更容易调试、修改和维护。

更便于多人协同合作开发。

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

5

过程访问修饰符过程访问修饰符Public:被该修饰符修饰的过程称为公共过程,可以在应用程序的任何地方被访问。

Private:被该修饰符修饰的过程称为私有过程,仅能由声明该过程的类或者模块访问。

Shared:被该修饰符修饰的过程称为共享过程,不与声明该过程的类的实例相关联,可以通过类名来直接访问。

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

6

过程访问修饰符过程访问修饰符Protected:被该修饰符修饰的过程称为受保护过程,仅能由声明该过程的类及其派生类访问。

Friend:被该修饰符修饰的过程称为友元过程,可以由包含该过程声明的应用程序中的任何类或者模块中访问。

Protected Friend:被该修饰符修饰的过程称为受保护的友元过程,可以从同一程序集、声明该过程的类及其派生类中访问。

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

7

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

◦ 过程体◦End Sub

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

8

◦[ 子过程名 ] 是将要创建的子过程的名称,其命名规则同变量命名规则,采用字母和下划线开头,由字母、数字和下划线组成。

◦[ 参数列表 ] 是在子过程中使用的参数,个数可以是 0 个或者多个。该项可选,如果不止一个参数,则使用逗号分开。参数的传递有传值和引用两种,详见 6.4节。

◦过程体则是组成该过程的语句集合。

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

9

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

Step2:进行窗体界面设计。

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

10

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

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

11

Step4:调用过程 Greeting。

1 Private Sub btn_OK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_OK.Click2 Greeting(tb_name.Text)3 End Sub

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

12

小结小结过程定义包含过程头、过程体和 End Sub关键字。

过程头由 Sub关键字开始,后跟过程名,之后是一对圆括号括起来的形参列表。

形参列表中包含对形参变量的声明。如果有多个参数,则用逗号分割。

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

13

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

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

14

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

◦ 函数体◦End Function

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

15

FunctionFunction 与与 SubSub 的不同的不同二者唯一不同的地方在于, Function函数的参数列表之后比 Sub子过程多了一项 As 返回值类型。

这是因为, Function函数允许函数体运行结束后,向调用过程返回一个结果,称为返回值,其类型由 As 返回值类型来定义。 Function函数有且仅有一个返回值。

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

16

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

Step2:窗体设计。

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

17

Step3:编写用于计算阶乘的Function函数 Fac。1 Function Fac(ByVal n As Integer) As Long2 Dim result As Long3 result = 14 Do While n > 05 result = result * n6 n = n-17 Loop8 Fac = result9 End Function

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

18

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

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

19

运行结果运行结果

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

20

小结小结函数定义包含函数头、函数体和 End Function关键字。

函数头由 Function关键字开始,后跟函数名,之后是一对圆括号括起来的形参列表。

形参列表中包含对形参变量的声明。如果有多个参数,则用逗号分割。

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

21

小结小结形参列表后面是关键字 As 返回值类型,用于定义函数返回值的类型。

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

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

22

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

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

23

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

VB.NET中的参数默认都是 ByVal类型的。

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

24

当实参按值传递时,仅仅是将实参的值赋值给形参变量。在被调用过程中,对该形参变量的修改不会影响到调用过程中实参变量的值。

与此相反,当实参按引用传递时,被调用过程可以直接访问甚至修改实参变量。

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

25

示例示例 11 :实现两个数的交换:实现两个数的交换Swap1,参数采用按值传递

Sub Swap1(ByVal x As Short, ByVal y As Short)

Dim t As Short t = x x = y y = tEnd Sub

Swap2,参数采用按引用传递

Sub Swap2(ByRef x As Short, ByRef y As Short)

Dim t As Short t = x x = y y = tEnd Sub

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

26

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

a = 10b = 20 Swap1(a, b)MessageBox.Show("a=" & a.ToString( ) & ";b=" & b.ToString( ))

√X

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

27

WhyWhy ??Swap1采用的是按值传递,被调用时,实参 a 将值 10传递给形参变量 x ,实参 b 将值 20传递给形参变量 y 。

在过程内部, x 和 y 的值进行了交换,即 x 值变为 20 , y 值变为 10,但是此次交换并没有影响到被调用过程中变量 a 和 b 的值。

因此, Swap1过程调用结束后, a 和b 的值没有发生变化。

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

28

而 Swap2采用的是按引用传递,被调用时,实参 a 将变量 a 地址传递给形参变量 x ,实参b 将变量 b 的地址传递给形参变量 y 。

此时,变量 a 和变量 x 指向同一个内存单元,变量 b 和变量 y 指向同一个内存单元。之后在过程内部, x 和 y 的值进行了交换。由于 x 和y 分别指向变量 a 和 b 的内存单元,因此此次交换也同时影响到了被调用过程中变量 a 和 b。

因此, Swap2过程调用结束后, a 和 b 的值成功的进行了交换。

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

29

两种参数传递方式的区别两种参数传递方式的区别按值传递方式,仅传递变量的值,实参变量和形参变量分别指向内存中的不同空间。

而按引用传递方式,传递的是变量的地址,实参变量和形参变量指向内存中的同一个空间。

10

10

a

x

10 a

x

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

30

几点建议几点建议如果要将子过程中的运算结果返回调用过程,参数传递时应该选用传地址方式;此时实参必须是同类型的变量名,而不能是常量或表达式。

形参是数组、自定义类型、对象等数据时,必须使用传地址方式。

除此之外,通常使用传值方式,以减少被调过程和调用过程之间的关联。

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

31

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

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

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

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

33

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

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

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

34

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

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

35

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

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

36

下面的代码声明了一个使用参数数组的Multi函数。◦1 Function Multi(ByVal ParamArray numbers( ) As Integer) As Integer

◦2 Dim n ,x As Integer 3 n = 1

◦4 For Each x In numbers◦5 n = n * x◦6 Next x◦7 Return n◦8 End Function

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

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)

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

38

6.4.4 6.4.4 按位置传递和按名称传按位置传递和按名称传递递在调用 Sub 或 Function过程时,可以按位置传递参数(即按照参数出现在过程定义中的顺序)或者按名称传递参数,而不考虑位置。

按名称传递参数时,指定参数的声明名称,后接冒号(:)和等号( = ),后面是参数值。可以按照任意的顺序提供命名参数。

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

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

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

40

可以按位置传递参数(以逗号分隔)来调用studentInfo过程,代码如下。◦studentInfo("Mary", 19, #9/21/1981#)

如果在一个按位置排列的参数列表中省略可选参数,必须用逗号保留它的位置。下面的示例调用了没有 age参数的 studentInfo过程。◦studentInfo("Mary", , #9/21/1981#)

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

41

另一种方法是,可以按名称传递参数(同样以逗号分隔)来调用studentInfo过程,代码如下。◦studentInfo(age:=19, birth:=#9/21/1981#, name:="Mary")

在单个过程调用中,可以同时按位置和按名称提供参数,代码如下。◦studentInfo("Mary", birth:=#9/21/1981#)