




已阅读5页,还剩252页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
VisualBasic程序设计教程 中 目录 第5章数组 整型 实型 字符型等数据类型都属于简单类型 而在实际应用中 常常要遇到处理相同类型的成批相关数据的情况 例如 为了处理某系几百个学生某门课的考试成绩 若在程序中定义几百个简单变量记录这些数值 显然是十分笨拙的 程序设计语言提供了一种解决此类问题的更为有效的数据类型 数组 数组是由固定数目的同类元素按一定顺序排列而成的结构类型数据 数组是程序设计中常用到的数据类型 当数组中每个元素只带有一个下标时 称这样的数组为一维数组 在计算机内存中 数组占据了一块连续的存储区域 数组名就是这块空间的名称 区域中每个单元都有自己的地址 该地址用下标表示 数组应该先定义后使用 定义数组的目的是通知计算机为其留出所需的存储空间 数组与普通变量一样 用来存放数据 且同一数组中的数据必须是同一类型的 5 2 1一维数组的声明 数组说明格式1 说明符 变量名 下标 As 类型 其中 说明符 为VisualBasic的保留字 不同的说明符可以定义数组的不同性质和作用范围 变量名 是数组名 是用户自定义的标识符 下标 用于定义数组元素的个数 下标值类型为长整型 Long 下标界值范围从 2147483648到2147483647 此种形式默认下标下界为0 类型 是指数组的类型 例如 Dima 8 AsInteger在这里 Integer是类型名 a 8 就是一维数组说明符 以上语句说明了下面几点 定义了一个名为a的一维数组 括号中的8规定了a数组含有9个元素 它们是a 0 a 1 a 2 a 8 类型名Integer规定了a数组中每个元素都是整型 在每个元素中只能存放整型数 每个元素只有一个下标 VisualBasic语言默认此数组第一个元素的下标值为0 称为数组下标的下界 因此 以上a数组中的最后一个元素的下标应该是8 称为数组下标的上界 5 2 1一维数组的声明 5 2 1一维数组的声明 VisualBasic编译程序将为a数组在内存中开辟如图5 1所示的9个连续的存储单元 在图5 1中标明了每个存储单元的名字 可以用这样名字直接来引用各存储单元 图5 1编译程序所开辟的存储单元 例如在程序中有说明 DimCounter 10 AsIntegerDimSum 20 AsDoubleDimname 15 AsString 5 2 1一维数组的声明 以上语句用Dim作说明符 与说明简单变量一样 它用于说明局部数组 也就是说 它可以出现在窗体层 模块和过程中 是最常用的说明形式 第一个语句建立了一个有11个元素的数组Counter 其下标从0到10 元素类型为Integer 它的元素有 Counter 0 Counter 1 Counter 2 Counter 10 带下标的数组元素也称为下标变量 第二个语句建立了一个数组Sum 有21个元素 其下标从0到20 元素类型为Double 第三个语句建立了一个数组name 有16个元素 其下标从0到15 元素类型为String 如果不想让数组的下标值从0开始算起 可以用OptionBase语句来改变它的起始值 例如 OptionBase1PublicStudents 10 AsInteger 将使数组项目变成10个 也就是由1到10 即此数组有Students 1 Students 2 Students 3 Students 10 数组说明格式2 说明符 变量名 下标to上界 As 类型 此种数组说明中 关键字to可以显式地规定下标下界 此时应满足下界 上界 例如在程序中有说明 DimCounter 1to10 AsIntegerDimSum 10to20 AsDoubleDimname 20to 20 AsStringCounter的下标值范围从1到10 Sum的下标范围从10到20 数组name的下标等于上标 即name退化成一个简单变量了 5 2 1一维数组的声明 5 2 2一维数组元素的引用 引用数组元素 下标变量 即在括弧中指定下标 在程序中 数组与其他变量的使用方式相同 即可参与运算 可以被赋值 在引用数组时 数组名 类型 维数以及下标的范围 应与定义时一致 同一模块中 数组和变量不可同名 数组由一组类型相同的元素组成 一维数组元素的基本引用方式如下 数组名 下标表达式 如 a 0 a i 1 等 应该建立起以下概念 一个数组元素实质上就是一个变量名 代表内存中的一个存储单元 一个数组占有一串连续的存储单元 在引用数组元素之前 必须先对数组进行定义 规定数组元素中下标表达式的值必须是整数 下标值的默认下限是0 上限是定义中的下标表达式的值 以上面定义的a数组为例 其定义的第一个数组元素是a 0 最后的一个元素是a 8 注意 下标表达式的值不得越界 在ViaualBasic语言中 一个数组不能整体引用 例如 对于以上定义的a数组 不能用a代表a 0 到a 8 这9个元素 1 给数组元素赋初值利用循环结构可以给已定义的数组赋初值 DimA 1To10 AsInteger 数组的每个元素是0Fori 1To10A i 0NextI2 数组的输入可通过InputBox函数输入数组中第i个元素的值 此方法适合输入少量数据 Dima 3 AsIntegerFori 0To3a i InputBox 输入a i 的值 运行时显示 输入a 1 的值 其中随着i值的变化 提醒用户输入相应元素Nexti对于大量的数据输入 为了便于编辑 一般不用InputBox函数 而用文本框再加某些技术处理 5 2 3一维数组的基本操作 3 数组的输出利用循环结构可以对已定义的数组进行输出 OptionExplicitPrivateSubCommand1 Click Dimn 1To3 AsIntegerDimiAsIntegerFori 1To3n i InputBox 请输入第 n i NextiEndSub程序运行后 单击命令按钮 执行事件过程Command1 Click 若输入5 10 15三个值 则窗体上显示的输出结果是 n 1 5n 2 10n 3 15 5 2 3一维数组的基本操作 4 2 3多分支选择语句 1 If Then Else语句 多分支结构 这种语句为多分支选择结构 即Then和Else后面的语句块包含另一个条件语句 语句形式如下 IfThen IfThen EndIf Else EndIf使用条件语句嵌套时 一定要注意If与Else If与EndIf的配对关系 例4 8 根据不同的时间段发出问候语 例如 0时至12时 显示 早上好 利用窗体装载 Load 事件 采用Print直接在窗体上输出结果 4 2 3多分支选择语句 过程中说明了一个具有3个元素的一维整型数组 分别用循环语句输入 输出数组元素的值 在循环体内 数组元素用循环控制变量i作下标 i值的不同表示数组元素不同 在程序中 数组元素的下标可以使用表达式 但表达式的结果只要不超出数组定义的上界和下界范围 下标表达式就是合法的 例如 若i 3 则n i 2 的值为5 下标表达式的值还可以是实数 此时VisualBasic将自动对其进行四舍五入取整 例如 n 2 1 0 4 的值是15 n 3 7 2 6 的值是5 5 2 4一维数组的应用 例5 1 按学号以数组顺序存储n个学生的成绩 要求输出最高成绩及相应的学号 OptionBase1PrivateSubCommand1 Click Constn 20DimScore n AsIntegerDimMax i codeAsIntegerMax 0Fori 1TonScore i InputBox 请输入第 Str i 个学生的成绩 If Score i Max ThenMax Score i code iEndIfNexti 5 2 4一维数组的应用 PrintPrint 最高分是 MaxPrintPrint 最高学分的学号为 codeEndSub 例5 2 将一个数组中的值按逆序重新存放 交换的要求是将数组第一个元素与最后一个交换 第二个与倒数第二个交换 以次类推 如原来顺序为10 3 4 5 6 2 按要求应改为2 6 5 4 3 10 OptionExplicitPrivateSubCommand1 Click Constn 5Dima n AsIntegerDimi tempAsIntegerPrint Enterarraya n Fori 0Ton a i InputBox 请输入第 NextiEndSub 5 2 4一维数组的应用 程序运行结果如下 Enterarraya 4567239 arraya 4567239Now arraya 9327654 5 2 4一维数组的应用 数学中矩阵的各个元素要用行 列位置标识 计算机上的每一个屏幕像素要用X Y坐标表示它的位置 类似这种数据结构 可用二维数组形式描述 在ViaualBasic中 拥有两个下标的数组就是二维数组 5 3二维数组 5 3 1二维数组的声明 数组说明格式1 说明符 变量名 下标1 下标2 As 类型 其中 说明符 为VisualBasic的保留字 不同的说明符可以定义数组的不同性质和作用范围 变量名 是数组名 是用户自定义的标识符 下标1 指此数组第一 下标2 指此数组第二维的大小 类型 是指数组元素的类型 数组元素类型可以是任意VisualBasic数据类型 例如 Dima 8 8 AsInteger在这里 Integer是类型名 a 8 8 就是数组说明符 以上语句说明了下面几点 定义了一个名为a的二维数组 括号中的8 8规定了a数组为含有两个下标的二维数组 它们的排列图5 2所示 5 3 1二维数组的声明 类型名Integer规定了a数组中每个元素都是整型 在每个元素中只能存放整型数 如下标个数有多个 则此数组为多维数组 数组说明格式2 说明符 变量名 下界to上界 下界to上界 As 类型 例如在程序中有说明 DimCounter 1to2 2to4 AsInteger则此Counter数组有6个元素 分别为Counter 1 2 ounter 1 3 Counter 1 4 Counter 2 2 Counter 2 3 Counter 2 4 5 3 1二维数组的声明 5 3 2二维数组的引用 二维数组元素的引用方式如下 数组名 下标表达式1 下标表达式2 1 给数组元素赋初值利用循环结构可以对已定义的数组赋初值 例 DimA 3 3 i jAsInteger 数组的每个元素是0Fori 0To3Forj 0to3A I j 0NextjNexti2 数组的输入可通过InputBox函数输入数组中某个元素的值 此方法适合输入少量数据 例 DimB 3 3 i jAsIntegerFori 0To3Forj 0to3 5 3 3二维数组的基本操作 B i j InputBox 输入a Str i Chr 44 Str j 的值 运行时显示 输入a 1 1 的值 其中随着i j值的变化 提醒用户输入相应元素NextjNexti3 数组的输出利用循环结构可以对已定义的数组输出每个数组元素的值 OptionExplicitPrivateSubCommand1 Click DimA 2 2 AsIntegerDimi jAsIntegerFori 0To2Forj 0To2 5 3 3二维数组的基本操作 A i j InputBox 请输入A A i j NextjNextiEndSub程序运行后 单击命令按钮 执行事件过程Command Click 若输入5 10 15 5 10 15 5 10 15九个值 则窗体上显示的输出结果是 5 3 3二维数组的基本操作 5 3 3二维数组的基本操作 A 0 0 5A 0 1 10A 0 2 15A 1 0 5A 1 1 10A 1 2 15A 1 0 5A 1 1 10A 1 2 15过程中说明了一个具有9个元素的二维整型数组 分别用循环语句输入 输出数组元素的值 在循环体内 用循环控制变量i作数组元素的第一维下标 用循环控制变量j作数组元素的第二维下标 i j值的不同表示数组元素的不同 5 3 4二维数组的应用 例5 3 求矩阵相乘C A B 设A B C分别为m p p n和m n的矩阵 按矩阵乘法的定义求C 若有一个4 3的数组A乘以一个3 2的数组B 将得到一个4 2的数组C 程序为 OptionexplicitPrivateSubCommand1 Click Constm 4 p 3 n 2Dima 1Tom 1Top AsIntegerDimb 1Top 1Ton AsIntegerDimc 1Tom 1Ton AsIntegerDimiAsInteger jAsInteger kAsInteger sumAsIntegerFori 1TomFork 1Topa i k InputBox 输入矩阵元素A Str i Str k Nextk iFork 1TopForj 1Tonb k j InputBox 输入矩阵元素B Str k Str j Nextj k Fori 1TomForj 1Tonsum 0Fork 1Topsum sum a i k b k j Nextkc i j sumNextj iPrint 输出矩阵 Fori 1TomPrint Forj 1TonPrintc i j NextjPrint NextiEndSub 5 3 4二维数组的应用 5 3 4二维数组的应用 则显示的输出矩阵为 例5 4 编一个将n阶方阵转置的程序 转置是指把矩阵的元素aij和aji交换 OptionExplicitPrivateSubCommand1 Click Form1 AutoRedraw TrueConstn 4Dima 1Ton 1Ton AsIntegerDimiAsInteger jAsInteger tempAsIntegerFori 1TonForj 1Tona i j InputBox 输入A Str i Str j Nextj iPrint 输入的矩阵为 Fori 1TonForj 1TonPrinta i j NextjPrintNexti 5 3 4二维数组的应用 Fori 1TonForj i 1Tontemp a i j a i j a j i a j i tempNextj iPrint 转置后矩阵为 Fori 1TonForj 1TonPrinta i j NextjPrintNextiEndSub由于转置矩阵行列交换 对角线元素不变 为了防止已交换过的两个元素被再次交换 在实施交换的嵌套For循环语句中 内循环的控制变量从i 1增加到n 5 3 4二维数组的应用 程序运行后 窗体显示是 5 3 4二维数组的应用 VisualBasic为适应各种不同的程序设计需要 允许数组有多种定义方式 5 4 1定义动态数组 定义数组的目的是为数组开辟所需的内存区域 前面用Dim语句说明数组时 都同时确定维数和下标个数 VisualBasic编译程序在编译时为它们分配了相应的存储空间 并且在应用程序运行期间内 数组都占有这块内存区域 这样的数组称为定长数组 当数据规模可以预知时 使用定长数组能够增加程序的可读性和提高程序的执行效率 但有时候 数组应定义多大 要在程序运行时才能决定 定义一个 足够大 的数组显然是不经济的 动态数组又叫可调数组 它提供了一种灵活有效的管理内存机制 能够在程序运行的任何时候改变数组的大小 VisualBasic为适应各种不同的程序设计需要 允许数组有多种定义方式 5 4 1定义动态数组 DimArray AsSingleSubForm Load ReDimArray 4 8 EndSub在窗体级声明了数Array为可变长数组 在Form Load 事件函数中重新指明二维数组的大小为5行9列 注意 在静态数组声明中的下标只能是常量 而在动态数组ReDim语句中的下标可以是常量 也可以是有了确定值的变量 在过程中可多次使用ReDim来改变数组的大小 也可改变数组的维数 每次使用ReDim语句都会使原来数组中的值丢失 可以在ReDim语句后加Preserve参数用来保留数组中的数据 但使用Preserve只能改变最后一维的大小 前面几维大小不能改变 5 4 2与数组操作相关的几个函数 1 Lbound函数 Ubound函数Lbound函数是用来返回数组下标的最小索引值的 Ubound函数是用来返回数组最大索引值的 例如 定义如下一个数组 Dims 10 ASIntegerPrintLbound s Ubound s 此时的运行结果会输出0和10两个数 因为在数组s中 s的最小下标索引是0 最大下标索引是10 对于多维数组 也可以使用Lbound和Ubound函数 但这个函数只能求出多维数组某一维的下标最值 例如下面的例子 OptionBase1Dims 0To9 3 PrivateSubcommand1 click PrintUbound s 2 打印第二维的下标上界PrintLBound s 1 打印第一维的下标下界 5 4 2与数组操作相关的几个函数 PrintLBound s 2 打印第二维的下标下界EndSub运行结果是输出3 0 1综上所述 可以看出 这两个函数的语法格式为 Lbound 数组名称 要求的数组的维数的标号 Ubound 数组名称 要求的数组的维数的标号 如果后面的参数省略不写的话 则默认为求数组的第一维下标的最值 2 IsArray函数IsArray函数用来判断一个变量是否属于数组 例如 PrivateSubCommand1 Click Dima 2 AsIntegerPrintIsArray a EndSub运行结果是打印出True 或者 PrivateSubCommand1 Click DimwAsInteger PrintIsArray a EndSub 5 4 2与数组操作相关的几个函数 运行结果是打印出False 3 Erase函数Erase函数是将某个数组所占的内存空间释放掉 归还给系统 在使用了Erase函数后 这个数组的元素就不能够再被引用了 要想重新使用它 就必须使用ReDim或Array语句重新声明 例如 下面的程序使用Array语句声明一个数组后 用Erase函数释放掉该数组所占的内存空间 输出数组元素的值 则系统会提示 下标越界 如果重新使用Array语句声明同名数组并输出数组元素的值 则程序正常运行 PrivateSubCommand1 Click Data Array 1 2 3 PrintData 1 EraseData PrintData 1 Data Array 1 2 3 PrintData 1 EndSub VisualBasic中使用的数组和其他高级语言中的数组是没有区别的 只是在VisualBasic中含有一种特殊的数组 控件数组 控件数组是由一组相同类型的控件组成的 它们有共同的控件名称 具有大部分相同的属性 建立控件数组时 系统会给每一个元素唯一的索引号 Index 通过属性窗口中的Index属性 就可以知道该控件的下标是多少 控件数组的第一个元素的下标是0 控件数组适用于若干个控件执行的命令有相同代码的场合 这样可以使这些控件共享这一段代码 事件过程 从而可以节约程序员编写代码的时间 使程序更加精练 结构更加紧凑 控件数组可以在设计中创建 方法是 在窗体上创建一个控件 对控件名称和一些属性进行设置 选中该控件用鼠标进行复制 Copy 和粘贴 Paste 操作 会出现询问是否创建控件数组的对话框 单击 是 按钮进行控件数组创建 在单击了 是 按钮后 在窗体中就会创建一个控件数组 下面的例子就是创建一个计算器中数字键和运算符号键的控件数组 然后对这些数字键可以采用同 5 5控件数组 一段代码来实现数字的输入 这样就可以减少程序员编写代码的任务 对于控件数组来说 它只限于一维结构 没有一个明确的上界 而且也不一定要使用连续的索引值 因为它的索引值可以被重新设置 例5 5 采用控件数组编写一个计算器 要求该计算器能够实现简单的加 减 乘 除运算 如图5 3所示 图5 3简单计算器 5 5控件数组 程序代码如下 PrivateSubCommand1 Click IndexAsInteger DimxAsInteger yAsInteger sAsIntegerx Val Text1 Text y Val Text2 Text SelectCaseIndexCase0s x yText3 Text sCase1s x yText3 Text sCase2s x yText3 Text sCase3s x yText3 Text sEndSelectEndSub 思考 什么是数组 数组元素的值怎样给定 动态数组的优点体现在哪里 在由控件数组构成的应用程序中如何识别是哪一个控件引发的事件 第6章过程 过程是现代程序设计中最重要的概念之一 从编程的角度来看 一个应用程序由若干个模块组成 每个模块由若干个更小的代码片段组成 这些代码片段被称为 过程 当编程人员设计好应用程序的界面以后 主要的任务便是构造过程 过程由代码组成 它们存储在窗体文件或模块文件中 VisualBasic系统为每个对象预先定义好了一系列的事件 用户不能增加也不能删除 当用户对某个对象发出一个动作时 在该对象上就发生了事件 然后自动地调用与该事件相关的事件过程 处理或响应事件的步骤就是事件过程 实际上 编写VisulBaic应用程序的主要任务就是判定对象是否响应某种事件以及如何响应该事件 当想让对象响应某个事件时 就编写该事件过程的程序代码 当用户对一个对象发出一个动作时 可能会产生多个事件 比如 当用户单击鼠标时便发生了Click MouseDown和MouseUp事件 编写VisualBasic程序时 并不要求对每个事件都编写代码 只要对感兴趣的事件过程编写代码即可 事件过程一般的格式如下 PrivateSub对象名称 事件 参数列表 EndSub对象的每个事件过程有固定的语法 所包含的参数个数也是由系统预先定义好的 不同事件过程有不同的参数 事件参数记录了事件发生时的状态 它们是编写程序必要的数据来源 通用过程能用来完成特定的功能 以Sub关键字开始 可以在事件过程或其他过程中通过过程名称调用Sub过程 通用过程的结构与事件过程的结构类似 一般格式如下 Private Public Sub 参数列表 语句块1 ExitSub 语句块2 EndSub例如 PrivateSubSubtest Print ThisisaSubProcedure EndSub说明 通用过程以Sub开头 以EndSub结束 在两者之间是描述操作的语句块 即 过程体 在一个通用过程内不能再定义另一个通用过程 即通用过程不能嵌套定义 6 3 1通用过程 Sub过程 的定义 6 3 1通用过程 Sub过程 的定义 格式中各参量的含义如下 关键字Private 私有 表示函数过程是私有过程 只能被本模块中的其他过程访问 不能被其他模块中的过程访问 关键字Public 公有 表示函数过程是公有过程 可以在程序的任何地方调用它 各窗体通用的过程通常在标准模块中用Public定义 在窗体定义的通用过程不仅可以在本窗体模块中使用 也可以在其他窗体模块中使用 的命名规则与变量名的命名规则相同 一个函数过程只能有一个唯一的名字 名字长度不得超过40个字符 不能与VisualBasic中的关键字同名 也不要与WindowsAPI函数同名 更不能与同一级别的变量同名 在同一个模块中 同一名称不能既用做又用作 类似于变量声明 在中出现的参数称为形式参数 简称为形参 各参数之间用逗号隔开 指明了调用时传送给过程的参数类型 个数和位置 它并不代表一个实际存在的变量 也没有固定的值 在调用此过程时它被一个确定的值所代替 形参的名字并不重要 重要的是其所表示的关系和调用时所给定的实际参数 每个参数的格式为 6 3 1通用过程 Sub过程 的定义 ByVal 变量名 As数据类型 如 mAsInteger这里的 变量名 是一个合法的VisualBasic变量名或数组名 如果是数组 则要在数组名后加上一对括号 数据类型 指的是变量的类型 可以是Integer Long Single Double String Currency Variant或用户定义的类型 如果省略 As数据类型 则默认为Variant 变量名 前面的ByVal是可选的 如果加上ByVal 则表明该参数是 传值 参数 如果没有加ByVal的参数称为 引用 参数 关于参数传递将在后面章节中作介绍 6 3 1通用过程 Sub过程 的定义 语句块 是VisualBasic的程序段 包括说明部分和执行部分 说明部分是对过程自身要用到的变量进行说明 这些变量局限于该过程之内 称为局部变量 执行部分是用来实现过程的功能 所有的可执行语句都必须放置在某一过程内 只有说明性语句才放在过程和函数之外 ExitSub语句使执行立即从该过程中退出 程序接着从调用该过程的语句之后的语句执行 在过程的任何位置都可以有ExitSub语句 执行到哪个ExitSub语句 哪个ExitSub起作用 EndSub标志着通用过程的结束 当程序执行到EndSub时 将退出该过程 并立即返回到调用语句下面的语句 6 3 2子过程的建立 自定义子过程有两种方法 1 利用 工具 菜单下的 添加过程 命令定义操作步骤如下 1 为想要编写函数的窗体 标准模块打开代码窗口 2 选择 工具 菜单下的 添加模块 命令 打开 添加模块 对话框 如图6 1所示 在该对话框中选择 新建 选项卡 然后双击 模块 图标 打开模块代码窗口 图6 1 添加模块 对 6 3 2子过程的建立 3 执行 工具 菜单中的 添加过程 命令 打开 添加过程 对话框 如图6 2所示 图6 2 添加过程 对话框 6 3 2子过程的建立 4 在 名称 框中输入要建立过程的名字 过程名中不允许有空格 如 Try 5 在 类型 组中选取 子过程 定义通用子过程 6 在 范围 组中选取过程的适用范围 可以选择 公有的 或 私有的 如果选择 公有的 则所建立的过程可用于本工程内的所有窗体模块 如果选择 私有的 则所建立的过程只能用于本标准模块 7 单击 确定 按钮 回到模块代码窗口 如图6 3所示 8 这时 VisualBasic建立了一个函数过程模块 在其中就可以编写代码 图6 3模块代码窗口 6 3 2子过程的建立 2 利用代码窗口直接定义操作步骤是 在代码窗口的通用代码段输入过程的名字 例如 输入PublicSubTry 按回车键后显示 PublicSubTry EndSub即可在PublicSubTry 和EndSub之间输入程序代码 调用引起子过程的执行 也就是说 要执行一个过程 必须调用该过程 子过程的调用有两种方式 一种是把过程的名字放在一个Call语句中 另一种是把过程名作为一个语句来使用 1 用Call语句调用子过程格式 Call 实际参数 Call语句把程序控制传送到一个VisualBasic的Sub过程 用Call语句调用一个过程时 如果过程本身没有参数 则 实际参数 和括号可以省略 否则应给出相应的实际参数 并把参数放在括号中 实际参数 是传送给Sub过程的变量或常数 实际参数如果有多个 之间用逗号分隔 实参与对应的形参名字不必相同 但是个数必须相等 而且实参的书写顺序与相应的形参的类型相符 6 3 3过程的调用 6 3 3过程的调用 1 没有参数的子过程 例6 1 简单子过程调用 PrivateSuboutput Print 没有参数的子过程 EndSubPrivateSubCommand1 Click Calloutput 由于没有参数 系统自动省去括号EndSub 2 带有单个参数的子过程 例6 2 给定半径 计算圆的面积 界面如图6 4所示 图6 4带有一个参数的过程 6 3 3过程的调用 PrivateSuboutput ByValrAsSingleDimsAsSingleConstpiAsSingle 3 14s pi r 2Label2 Caption 半径为 r 的圆 面积为 sEndSubPrivateSubCommand1 Click DimradiusAsSingleradiuse Val Text1 Text Calloutput radiuse EndSub 6 3 3过程的调用 3 带有多个参数的子过程 例6 3 给定半径和圆周率 计算圆的面积 界面如图6 5所示 图6 5具有两个参数的过程 6 3 3过程的调用 PrivateSuboutput ByValrAsSingle ByValpiAsSingle DimsAsSingles pi r 2Label2 Caption 半径为 r 的圆 面积为 sEndSubPrivateSubCommand1 Click DimradiusAsSingleDimpAsSingleradius Val Text1 Text p Val Text2 Text Calloutput radius p EndSub 6 3 3过程的调用 2 把过程名作为一个语句来使用格式 在调用子过程时 当省略关键字Call 就成为调用子过程的第二种方式 与第一种方式相比 它有两点不同 一是省去了关键字Call 二是略去了 实际参数表 的括号 例如 PrivateSubCommand1 Click DimradiusAsSingleDimpAsSingleradius Val Text1 Text p Val Text2 Text outputradius pEndSub 函数过程能用来完成特定的功能并返回相应的结果 以Function关键字开始 可以在事件过程或其他过程中通过函数名称调用函数过程 6 4 1函数过程的定义 函数过程定义的格式 Private Public Function 参数表列 As类型 语句块1 过程名 表达式 ExitFunction 语句块2 EndFunction说明 函数过程以Function开头 以EndFunction结束 在两者之间是描述操作的语句块 即 函数体 在一个函数过程内不能再定义另一个函数过程 即函数过程不能嵌套但可以调用其他函数过程或子过程 格式中各参量的含义如下 6 4 1函数过程的定义 函数过程以Function开头 以EndFunction结束 在Function和EndFunction之间是描述过程操作的语句块 称为 函数体 格式中的Private Public 过程名 参数表列 语句块 ExitFunction EndFunction的含义与Sub过程中相同 As类型 指明了函数过程返回值的数据类型 返回值即使得名具有值 如果没有 As类型 默认的数据类型为Variant 当函数过程有返回值时 必须将返回值通过一个赋值语句赋给 否则该函数过程返回一个默认值 数值函数过程返回0 字符串函数过程返回空字符串 因此 为了能使一个函数过程完成所指定的操作 通常要在过程中为赋值 通常情况下 在函数过程的任意位置都可以出现这种赋值 6 4 2函数过程的建立 函数过程的建立与子过程的建立过程相同 下面是一个函数过程的例子 例6 4 编写一个求最大公约数的函数过程 Functiongcd ByValxAsInteger ByValyAsInteger AsIntegerDoWhiley0Reminder xModyX yY reminderLoopgcd xEndFunction上述过程通过反复相除求最大公约数 它有两个参数 均为传值参数 函数值为整数 6 4 3函数过程的调用 Function过程的调用比较简单 因为可以像使用VisualBasic内部函数一样来调用函数过程 根据函数有无返回值 可以利用两种形式对函数过程进行调用 变量 说明 当函数过程有返回值时 代表了函数过程的返回值 所以函数过程不能作为单独的语句加以调用 被调用的函数过程必须作为表达式或表达式的一部分 参与与其他量的运算 用Call语句调用函数过程格式如下 Call 或 说明 Call语句把程序控制传送到一个VisualBasic的函数过程中 用Call语句调用一个过程时 如果过程本身没有参数 则 参数列表 和括号可以省略 否则应给出相应的实际参数 并把参数放在括号中 参数列表 是传送给函数过程的变量或常量 如CallTry a b 函数过程无返回值时 调用方法同子过程的调用 6 4 3函数过程的调用 在 例6 4 中我们编写了求最大公约数的函数gcd 该函数的类型为Integer 它有两个整型参数 下面的事件过程调用了该函数 Subform Click DimaAsInteger bAsIntegera 96 b 64x gcd a b print G C D xEndSub上述事件过程中的x gcd a b 就是调用gcd函数的语句 调用时的实际参数分别为96和64 调用后的返回值放入变量x中 6 4 3函数过程的调用 图6 6用函数计算阶乘 例6 5 编写程序 计算6 8 9 的值 界面如图6 6所示 下面用函数过程实现求阶乘 Functionfact1 nAsInteger AsDoubleDimvalAsDouble iAsIntegerval 1Fori 1Tonval val iNextifact1 valEndFunction 6 4 3函数过程的调用 调用函数过程fact1 PrivateSubCommand1 Click DimfactvalAsDouble sumAsDoublefactval fact1 6 sum sum factvalfactval fact1 8 sum sum factvalfactval fact1 9 sum sum factvalLabel1 Caption 用函数过程实现 vbCrLf 6 8 9 val sum EndSub 在调用过程时 可以通过参数向子过程和函数过程中传递必要的信息 过程中的代码通常需要这些信息才能完成它的工作 一般来讲 在编制过程时 要考虑过程和调用它的过程间是如何传递数据的 即调用过程的程序要为过程准备哪些输入到过程中用的 待处理加工的数据 输入量 过程执行完后 要把哪些结果 输出量 传送回来 正确地提供一个过程的输入数据和正确地引用其输出数据 是使用过程的关键问题 这就是调用过程和被调用过程之间的数据传递问题 也就是说 在调用一个过程时 必须把实际参数传送给过程 完成形式参数与的结合 然后用实际参数执行调用的过程 6 5 1形式参数与实际参数 形式参数 形参 是在Sub Function过程的定义行中出现的变量名 是接收数据的变量 形参只是某些物理量的代表符号 体现物理量之间的逻辑关系 在使用前要向其输入数据 使用后在某些情况下还要通过其获得数据 形参之间用逗号隔开 形参表中的形参可以是 后面跟有左右括号的数组名 除定长字符串之外的合法变量名 实际参数 实参 则是在调用Sub或Function过程时传送给Sub或Function过程的常量 变量 表达式或数组 实参都含有实实在在的数据 实参之间用逗号分开 实参可以是常数 表达式 合法的变量名 后面跟有左右括号的数组名 6 5 2参数传递 在ViaualBasic中 参数通过两种方式传送 即传值和传地址 1 传值所谓传值是指以形参为传值参数 ByVal 时 ViaualBasic为形参分配新的存储空间 然后把实参中的值一一复制到相应的形参中作为形参的初值 实参与形参断开了联系 被调用过程中的操作是在形参自己的存储单元中进行的 当过程调用结束时 这些形参所占用的存储单元也同时被释放 所以实参中的值在过程调用前和调用后保持不变 传值方式用关键字ByVal来实现 不可以省略关键词 且实参为变量 常数或表达式 6 5 2参数传递 例6 6 检验ByVal方式实参在调用前 后的值 界面如图6 7所示 PrivateSubtref ByValaAsInteger a a 1Print 在过程体内 a aEndSubPrivateSubCommand1 Click DimwAsIntegerPrint 在过程调用之前w wCalltref w Print 在过程调用之后w wEndSub 图6 7传值方式 6 5 2参数传递 2 传地址传地址方式用关键字ByRef来实现 可以省略关键词 当形参为传地址参数 ByRef 时 VisualBasic并不为形参开辟另外的存储空间 形参直接使用实参的地址和数值 所以按地址传递参数允许被调用过程访问实参 且可为调用过程带回数据 由于过程中使用的形参是实参本身 因此 如果在调用过程中改变了形参的值 则当过程结束后 实参的值也发生了相应的变化 6 5 2参数传递 例6 7 检验ByRef方式实参在调用前 后的值 界面如图6 8所示 PrivateSubtref ByRefaAsInteger a a 1Print 在过程体内 a aEndSubPrivateSubCommand1 Click DimwAsIntegerPrint 在过程调用之前w wCalltref w Print 在过程调用之后w wEndSub 图6 8传地址方式 6 5 2参数传递 一般来说 传地址比传值更能节省内存并提高效率 因为在定义通用过程时 过程中的形参只是一个地址 系统不必为保存它的值而分配内存空间 只简单地记住它地一个地址 使用地址可以使ViaualBasic更有效地操作 但对于整数来说 这种效率不太明显 而对于字符串来说 效率会得到明显的提高 6 5 3有关过程之间数据传递的几点说明 究竟何时使用传值方式 何时使用传地址方式呢 下面是几条可供参考的原则 整型 长整型和单精度参数 如果不希望修改实参的值应选择值传送方式 为了提高效率 字符串和数组应通过地址传送 用户定义的类型 如记录 和控件只能通过地址传送 其他数据类型 可以用两种方式传送 但最好用传值方式传送 以避免错用参数 最好用传值方式来传送所有变量 字符串 数组 记录类型除外 当程序编写完成并调试正确后 再把部分参数改为传地址 以提高程序运行速度 数组可以作为函数或过程的参数 在形参表中 数组名后面应该添加一对括号 以区别于其他变量 数组在做参数时 传递类型只能是传地址 例6 8 数组作为函数参数 以调用过程的方式输出数组 界面如图6 9所示 PrivateSubtryout minAsInteger maxAsInteger k AsInteger DimiAsIntegerFori minTomaxPrintk i NextiEndSub 图6 9数组作过程参数输出 PrivateSubCommand1 Click Dimw 3 AsIntegerDimjAsIntegerForj 0To3w j jNextjCalltryout 1 3 w EndSub数组作为参数时经常会用到求数组上下标的函数 Lbound Ubound VisualBasic应用程序由若干个过程构成 这些过程一般保存在窗体文件 frm 或标准模块 bas 中 在过程中变量是必不可少的 变量和过程都可以出现在不同地方 因此作用范围是不尽相同的 变量 过程可被访问的范围称为变量或过程的作用域 6 7 1变量的作用域 变量的作用域决定了可访问该变量的子过程和函数过程 变量按作用域分为局部变量 窗口 模块级变量和全局变量 1 局部变量局部变量是指在过程内用Dim的语句声明的变量 或不加声明直接使用的变量 如图6 10所示 图6 10局部变量的使用 6 7 1变量的作用域 局部变量只能在一个过程中使用 其他过程不能访问此变量 局部变量随过程的调用分配存储单元 并在声明的过程内进行数据的存取 一旦过程体结束 变量的内容自动消失 占用的存储单元释放 不同的过程中可有相同名称的变量 彼此互不相干 在下次过程执行时 所有局部变量的值初始化为0或空 使用局部变量 有利于程序的调试 2 窗体 模块级变量窗体 模块级变量指在一个窗体 模块的任何过程之外声明的变量 在代码窗口中选择左边的下拉框为 通用 然后选择右边的下拉框为 声明 用Dim或Private语句声明的变量 可被窗体 模块的任何过程访问 如图6 11所示 6 7 1变量的作用域 图6 11非局部变量使用 3 全局变量全局变量是指在一个窗体 模块的任何过程之外以Public关键字声明的变量 即在 通用声明 段中用公共的语句声明的变量 可被应用程序的任何过程或函数访问 全局变量的值整个应用程序中始终不会消失和重新初始化 只有当整个应用程序执行结束时 才会消失 不同作用范围的3种变量声明及使用规则如表6 1所示 注意 不能在过程中声明全局变量 只能在模块的声明段中声明全局变量 E1 与 窗体 模块级变量 一样 已修改 6 7 1变量的作用域 表6 1不同作用范围的3种变量声明及使用规则 6 7 2过程的作用域 一般VisualBasic应用程序的代码存储在3种不同的模块中 即窗体模块 标准模块和类模块 在本章只介绍窗体和标准模块文件 类模块在以后章节介绍 过程的作用域分为 窗体 模块级和全局级 1 窗体 模块级它是在某个窗体或标准模块内定义的过程 定义的附属过程或函数过程前加Private的关键字 过程只能被本窗体 在本窗体内定义 或本标准模块 在本标准模块内定义 中的过程调用 2 全局级它是在某个窗体或标准模块中定义的附属过程或函数过程 其默认是全局的 也可在过程前加上关键字进行说明 全局级过程可供该应用程序的所有窗体和所有标准模块中的过程调用 其调用方式根据过程所处的位置不同 有两种调用方式 在窗体定义的过程 当外部过程要调用时 应在被调用的过程名前加上所处的窗体名 在标准模块定义的过程 如果过程名唯一 则任何外部过程都可以直接调用 否则应在被调用的过程名前加上所处的标准模块名 6 7 2过程的作用域 例6 9 在下面一个窗体文件中进行不同级的变量声明 PublicaAsIntegerDimbAsIntegerSubprod DimaAsIntegera a aForm1 a 2b 2Print prod子程序中 Print 局部变量a a 全局变量a Form1 a 窗体 模块级变量b bPrintEndSub 命令按钮的Click 事件代码 PrivateSubCommand1 Click 6 7 2过程的作用域 DimaAsIntegerShow ClsFontSize 10a 5Form1 a 1b 1Print 调用prod前 Print 局部变量a a 全局变量a Form1 a 窗体 模块级变量b bPrintCallprodForm1 a Form1 a 1 b 1Print 调用prod后 Print 局部变量a a 全局变量a Form1 a 窗体 模块级变量b bEndSub 6 7 2
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《2025书画居间合同》
- 物业管理费收取标准及合同模版
- 旅游合同购物补充协议书范本
- 房屋屋顶防水维修合同与房屋屋顶防水维修合同范本5篇
- 村里雇佣合同5篇
- 日语翻译服务合同6篇
- 广告创意委托合同
- 财务理财合同2025版规范
- 2025广东广州市增城区教育局招聘广州增城外国语实验中学教师10人(编制)模拟试卷及答案详解1套
- 2025年2月山东领取济宁市份普通话水平测试等级证书模拟试卷及答案详解(易错题)
- 2025年全国保密教育线上培训知识考试试题库有含答案
- 2025年上海科学考试题目及答案
- 试点先行人工智能+智能客服系统可行性分析
- 兵团面试题目及答案
- 2025-2030中国基建投资拉动下工程机械需求预测与市场分析
- 胰岛素泵专家共识课件
- 电梯自行检测合规指南
- 人教版(2024)八年级上册数学全册教案
- 2025年住院医师规培-新疆-新疆住院医师规培(胸心外科)历年参考题库典型考点含答案解析
- 2025年低压电工证考试题库及答案
- 足球大单元教学计划
评论
0/150
提交评论