VB6.0 运行过程中win7和win10内存占用用一直增大,直到软件崩溃

当前位置: >>
VB6[1].0第3版教材课件
Visual Basic程序设计课件 1.0版→目录 目1 引言录×关闭本课件7 数组与自定义数据类型 8 内部控件2 程序设计入门 3 数据类型、常量与变量 4 运算符与表达式 5 控制结构 6 过程
打开各章例题9 内部函数10 绘图 11 多模块程序设计 12 文件操作打开各章习题 计算机编程语言的分类(1)机器语言 (2)汇编语言 (3)面向过程的语言(如:C、Fortran、Basic、Pascal等 ) (4)面向对象的语言(如Visual Basic、C++、C#、Java、Object Pascal 等) 程序的执行方式和运行环境 (1)解释型。源程序必须在编程环境的支持下才能运行。 (2)编译型。生成直接运行于操作系统之上的可执行文件.exe。 编译型具有执行速度快,代码效率高,保密性好等优点。 面向对象的基本概念 “对象”与“类” 的概 念任何事物都可以被看作“对象”(Object) “类”(Class)是同种对象的总称。 例如:“人”是一个类,每个具体的人是 一个对象。在程序设计中,类和对 象是事先定义好的。例如:“按钮”是一个 类,每个具体的按钮是 一个对象。 面向对象的PME模型 属性 任何对象都可以从以下三个 方面进行描述: (1)“属性”(Property) 对象所具有的特性。 (2)“方法”(Method) 对象可能执行的操作或行为。 (3)“事件”(Event) 对象可以识别并作出反应的 外部刺激。对象:一只气球?名称 =XX ?材料= XX ?直径 = XX ?颜色 = XX ?厚度 = XX ?飘浮 ?上升 ?下降 ?膨胀 ?缩小 ?爆炸 ?被释放 ?被扎 ?被打气 ?被放气方法事件 属性?姓名 = 张三 ?性别 = 男 ?身高 = 1.7米 ?国藉 = 中国 ?年龄 = 19岁 ? …… ?跑步 ?学习 ?笑 ?唱歌 …… ?遇到高兴的事情 ?下课了 ?…...方法对象:一个人事件不同对象之间的关系一个“系统”是由多个相互联系的对象组成(对象的数目和种 类由系统的复杂程度决定)。同一系统中的对象之间通过相互作用 (方法与事件)来改变各自的属性,使整个系统保持运动和发展。 对于同一个对象,它的属性、方法和事件之间存在极为密切的 关系:事件的发生→方法的执行→属性的改变。 Visual Basic 简介 Visual Basic 发展史VB 1.0 →VB 3.0 →VB 4.0 →VB 5.0 →VB 6.0 →VB.NET 1.0 →VB.NET 1.1 20世纪90年代初 → 1997年→ 1998年 →2001年 → 2003年 ↓ ↓ 中文学习版 VB 2005 中文专业版 2005年 中文企业版Visual Basic 的优点和缺点 Visual Basic的优点是语言简单易学,引入了“面向对象”和“事 件驱动”等先进思想,支持ActiveX控件、VBS和VBA,对网络和 数据库的编程有良好的支持,拥有完全的中文界面和帮助系统。缺 点是可移植性不好,只适用于32位Windows。本课程使用:VB 6中文企业版+SP2+WinXP+MSDN帮助 Visual Basic 6的启动方法(2)“开始”菜单(3)“程序”子菜单(4)“VB6”子菜单(5)此菜单项启动VB集成环境(1)“开始”按钮 第2章 程序设计入门 Visual Basic 6的集成开发环境主菜单主工具栏 工程窗口 对象窗口 属性窗口 代码窗口 立即窗口 本地窗口 工具箱 窗体布局窗口窗体对象 Visual Basic 工具箱窗口 PictureBox 控件 Label 控件 Frame 控件 CheckBox 控件 ComboBox 控件 HScrollBar 控件 TextBox 控件 CommandButton 控件 OptionButton 控件 ListBox 控件 VScrollBar 控件 DriveListBox 控件 FileListBox 控件 Line 控件 Data 控件Timer 控件DirListBox 控件 Shape 控件 Image 控件 Visual Basic 集成环境的 “工程”窗口和“属性”窗口 Visual Basic 集成环境的“对象”窗 口 一、向窗体上添加控件的方法 (1)单击图标,再拖动 (2)双击图标 (3)Ctrl键+单击图标,再拖动 (4)复制+粘贴二、选择控件的方法三、改变控件的大小和 位置 程序的设计、运行和中断状态 (1)设计状态 设置对象、编辑代码。 (2)运行状态 解释型地运行程序。 (3)中断状态 调试程序,进行排错。 可以在三种状态之间进行切换。 窗体(Form)对象窗体是窗口的框架,是VB程序最基本的对象,是各类控件的 容器。VB开发环境为每个窗体模块自动地创建了一个窗体对象。 Form对象的常用属性Name:对象名。用于标识对象的字符串。对象名必须满足以下条件: (1)必须以字母开头 (2)可以包含字母、数字和下划线,不能包括标点和空格 (3)不能多于40个字符 (4)不能与其它公共对象重名,可以与关键字相同,但应避免 (5)在同一模块下,不能重名 (6)建议为对象名加上类型前缀Caption:显示在窗体标题栏上的文字。 Visible:窗体是否可见,True或 False。 Icon:窗体图标。与一图标文件相联系。如为“无”则使用默认图标。 ControlBox:窗体是否有图标、系统菜单和最大化、最小化与关闭按钮。 MaxButton与MinButton:是否显示最大化与最小化按钮,值为True或False。只 有二者均为False时才不显示,否则设为False者只以无效显示。 BorderStyle:边框类型。决定窗体是否可缩放、标题栏是正常还是窄、是否在任 务栏上出现等。该属性对MinButton、MaxButton属性的设置有影响。 Left、 Top属性:窗体相对于屏幕的位置。坐标值的默认单位是缇(twip),1缇 等于1/567厘米。 Width 、Height属性:窗体的宽度与高度。默认单位也是缇。 Moveable属性 :True/False,False时窗体不能被鼠标拖动。 Enabled属性: True/False,False时窗体及上面的控件不响应用户的操作。 WindowState属性:取值为0、1、2,决定窗体还原、最小化、最大化状态。 Picture属性: 指定一个图片文件,用为窗体的背景图。 对象的每个属性反映了该对象某个方面的特 性。同一个对象的不同属性之间可能相互影 响。程序设计阶段可以在属性窗口中对属性 的值进行设置,(有些属性不能在设计时设 置;有些属性的设置只有在运行时才反映出 来)。在程序进行过程中,程序代码可以读 取或重新设置属性的值。有一些属性的值只 能在设计阶段设置,程序运行过程中这些属 性是只读的。 在程序中对对象的属性进行存取要以如下格 式:“对象名.属性名”。如: frmFirst.Height = 1200 属性的分类 (1)在设计和运行状态下都可设置的属性 (2)只能在设计时设置,不能在运行时设置的属性。如对象的 Name属性。 (3)只能在运行时设置,不能在设计时设置的属性。 (4)在设计和运行状态下都可设置,但只有在运行时才能生成的 属性。如Visible属性。 运行时对象属性的读写方法 访问对象属性的格式: 对象名.属性名 如: Form1.Caption 通过此格式可以读取属性的值,也可以设置属性的值。 如: Form1.Caption = &你好!Visual Basic & 或: x = Form1.Left Form对象的常用方法Move方法,语法为:对象名.Move Left, Top, Width, Height该方法将 object 对象移动到以 left, top 定义的新位置。同时可以改变该对象 的大小(以 width , height为新的宽与高)。其中 left 参数必须给定。但是,要给 定任何其它的参数,必须先给定出现在语法中该参数前面的全部参数。 例:设frmFirst为一窗体对象名。 frmFirst.Move 00,2000 ?既移动位置,又改变大小 frmFirst.Move
?只移动 frmFirst.Move 1000 ?只左右移动 frmFirst.Move 1000, ,1200 ?错误,缺少参数Move方法同时改变了Left, Top, Width与Height属性的值。效果与分别设置这些属 性的值等效。 Hide方法,语法为:对象名.Hide此方法将object对象隐藏,并将其Visible属性设置为 False。窗体被隐藏之 后,就不能响应用户的操作。该方法无参数。 某些方法的执行改变一些属性的值,有些方法的执行结果可能受一些属性的 影响。方法的执行可能等效于对一些属性的修改。 Show方法:使窗体从隐藏状态变为显示状态。对象名.ShowShow方法有两个参考,将在第11章讲解。 Print方法:在窗体表面上显示指的内容。对象名. Print?[“,|;”分隔的输出项]Print支持以逗号或分号分隔的多个输出项的值,每个输出项可以是属性、变 量、常量或表达式。 默认情况下,每调用一次Print方法将在窗体上显示一行内容。 Print方法的详细用法见第10章。 窗体Form对象的常用事件事件是对象能够识别的外部刺激,该刺激既可能来自于用户,也可能来自于操作 系统。 Click事件:当用户在窗体上(除标题栏和边框)单击鼠标左键或右键时引发。 Click事件过程:当对象接收到Click事件时所执行的代码。窗体的Click事件语法: Private Sub Form_Click() ……(语句组) End Sub 用户可以把想让对象对该事件所做的反应以VB语句的形式写在事件过程中。在 一个对象的事件过程中,可以设置其自身的或其它的对象的属性、执行其自身的 或其它的对象的方法、甚至可以调用自身的或其它的对象的事件过程。DblClick事件:当用户在窗体上(除标题栏和边框)快速双击鼠标键时引发。 DblClick事件过程:接收到DblClick事件时执行的代码,DblClick过程语法格式: Private Sub Form_DblClick() ……(语句) End SubResize事件:当窗体因任何原因大小发生变化时(或第一次显示窗体时)引发引 事件。在拖动边框窗体改变大小时,会连续引发多个Resize事件。 Load事件:窗体在加载显示时此发此事件,常用来对窗体或控件进行初始化。 “代码”窗口的使用打开【例2.1】打开【例2.2】 命令按钮(CommandButton)对象常用属性Name:对象名。要符合VB对对象名的要求。建议为按钮对象名加上“cmd”前缀。 Left、 Top:命令按钮在窗体上的位置。坐标值的默认单位是缇。 Width 、Height :按钮的宽度与高度。默认单位也是缇。 Caption:显示在按钮表面上的文字。可以使用“&”字符与其后的字母组成快捷键。 Visible: True 或False。该按钮是否可见。 Enabled: True 或False。False时按钮变灰,不能被点击。 Value:将该属性设为True可以触发按钮对象 的Click事件。只能在运行时设置。TopDefault:若该属性为True,则按钮对象为默认 按钮。不管焦点在哪个控件上,用户按回车键, 均触发按钮的Click事件。默认按钮有较粗的边 框。一个窗体上只能有一个按钮的Default属性 为True。 Cancel:若该属性为True,则按钮对象为默认的 “取消”按钮。不管焦点在哪个控件上,用户按 “ESC”键,均触发按钮的Click事件。LeftTop Left Width 命令按钮对象的常用方法和事件Move方法,此方法在窗体上移动按钮对象,参数的意义与窗体的Move方法相同。 object.Move Left, Top, Width, HeightClick事件:当用户在按钮表面上单击鼠标左键产生Click事件。另外下列方法也 能触发按钮的Click事件: (1) 用Tab键把焦点移动到该按钮上,然后按空格或回车键。 (2)按快捷键(Alt + 具有下划线的字母) (3) 如为窗体的缺省按钮,按回车键。 (4) 如为窗体的默认“取消”按钮,按ESC键。 (5 )在运行阶段设置属性:object.Value = True Click事件过程:当对象接收到Click事件时所执行的代码。按钮的Click事件语法: Private Sub object_Click() ……(语句组) End Sub 命令按钮对象不支持鼠标双击事件,即无DblClick事件。双击操作被理解为两个 单击操作。 窗体与控件事件过程名的区别: 对于窗体对象,其事件过程名为“Form_事件名”,与其对象名无关。 对于控件对象,其事件过程名为“对象名_事件名”,用到了其对象。打开【例2.3】 文本框(TextBox)对象的常用属性Name:对象名。 Left、 Top、Width 、Height、Visible、Enabled 属性与命令按钮的意义相同。 Text:文本框中的文本内容(默认属性)。 MaxLength:限制文本框中的文本的最大长 度(字符个数)。如果为0,则长度只受系 统限制。 MultiLine:为True时,文本框中可以显示 多行内容,最多可包含32K个字符。False 时,忽略换行符,最多可包含2048。 ScrollBars:设置文本框的滚动条,有0~3共4个取值。只有MultiLine属性为True 时,此属性才有意义。 Alignment:文本框中文本相对与文本框的对齐方式。须将MultiLine设为True。 PasswordChar:设置口令字符。须将MultiLine设为False。 Appearance:文本框是平面的还是立体的。 Locked:为True时,文本框的内容不能被编辑(与将Enabled设置为False不同) 。 SelLength、 SelStart和 SelText:分别为当前选定文本的长度、选定文本的起始 位置(以0为起点)与选定文本的内容。这三属性只在运行时使用。 文本框(TextBox)对象的方法与事件Move方法:用法与窗体相同。 Click事件、DblClick事件:因为文本框控件已具有内在的编辑功能,一般不必 编写其Click和DlbClick事件过程。 Change事件:当文本框的内容发生改变时引发Change事件。 Private Sub object_Change() ……(语句) End Sub打开【例2.4】 标签(Label)对象标签可以用来对其它没有标题的控件(如 文本框)进行说明,也可用来显示一些程 序运行过程中的提示信息。标签对象显示 的内容不能由用户直接修改,但由程序代 码修改。常用属性Name:对象名。Left、 Top、Width 、Height、Visible、Enabled 属性与命令按钮的意义相同。 Caption:标签上显示的文字内容。可以使用“&”来为标签创建快捷键。标签本 身并不能拥有输入焦点。当用户按快捷键时,会把焦点传递给Tab键次序中下一 个可拥有焦点的控件。 与文本框的Text属性不同,标签控件Caption属性的值不能由用户直接修改, 但可以由程序修改。 BorderStyle:True/False。当此属性为True时,标签有边框。默认值为False,即 无边框。AutoSize和WordWrap :这两个属性决定标签大小是否随显示的文本 内容变化,以及变化时是垂直还是水平扩展。 Label对象的常用事件和方法标签控件支持:Move方法、Click事件、DblClick事件与Change事件。 当标签Caption属性值变化时,引发Change事件。因为标签控件主要的作用是描述其他控件,显示的是形态文本。一般情况 下,不必编写其事件过程。打开【例2.5】 Visual Basic 语法规则1. 字母的大小写问题,关键字 2. 语句:程序以语句为单位,一般情况下,一条语句占一行。 3. 续行:如果语句太长,可以分为连续的多行书写,这时,未完的行要以空格与 下划线(称为“续行符”)结尾。注意分行时要避开关键字、对象名、过程名。 如: lblMyFirst.Caption= lblMyFirst.Caption _ +12313 4. 一行中写多条语句:要在一行中写多条语句,可在多条语句之间插入冒号作为 分隔。如: txtFirst.Text=“Hello” : frmOpen.Top=1000 : frmOpen.Left=1200 5. 注释:可在程序中加入以单引号开头的解释性的文字,单引号为“注释符”, 这些文字为注释内容。注释内容在程序执行时被忽略。注意:在续行符后不能写 注释。如: ' 这是日编写的 txtMy.Text = &您好!& ' 在文本框中向用户问好 6. 行号与标号 7. 英文符号与中文符号 8. 程序行的缩进,与源程序的美观 Visual Basic开发程序的主要步骤 1 2 3 4 5 预备工作 建立界面 设置属性 编写代码、进行调试 编译未完成或出错进入VB集 成开发环境添加对象, 编写代码保存打开 源程序 *.vbp、*.frm *.frx、*.bas文件解释性 试运行完成编译 可执行文件 *.exe文件 工程中的模块与文件为编制一个应用程序而创建的所有源文件统称为一个“工程”(Project)。一 个工程有一个工程文件(vbp,vbw),另外还有多个模块文件。 (1)窗体模块 窗体模块包含窗体及其控件的定义、属性设置,以及代码窗口中的程序行。窗 体文件的扩展名为 .frm ,如果设置了对象的ICO或Picture属性,会生成同名 的.frx文件。 (2)标准模块 标准模块包含数据类型、常数、变量、外部过程和公共过程的公共的或模块级 的定义。标准模块文件以 .bas为文件扩展名。 还可能用到其他类型的模块。 保存和打开工程(1)保存工程时先提示保存各模块文件,最后提示保存工程文件。 (2)打开工程时,直接打开工程文件即可。 (3)应该将一个工程中的所有文件保存在同一个文件夹中,便于 管理。 (4)不能在VB集成环境之外移动工程中的模块文件或对其进行 重命名。这样会导致工程无法打开。 生成可执行文件 (1)通过“文件”菜单中的“生成” 命令可执行文件.exe。可指定可执行 文件名和保存位置。 (2)可执行文件可脱离源程序与VB 环境单独运行。 (3)可执行文件需要一些中间文件 的支持才能运行。 第3章 数据类型、常量与变量 基本数据类型1 数值型 类型名 中文名 字节 表示范围 精度IntegerLong整型长整型24-3- ~ 精确精确6-7位有效数字15位有效数字SingleDouble单精度浮点型 4双精度 浮点型 8-3.402823E ?1038 ~ 3.402823 ? 1038-1.32?10308 ~ 1.32 ?10308Currency 货币型Byte 字节型81-477.5808 ~ 477.58070~25515位整数,4 位小数精确 2 String(字符串型) 字符串是指连续的字符序列。字符串数据类型是专门用来存放文 字信息的。字符串型又分为“定长字符串型”和“变长字符串型” 两大类。字符串类型所占的内存空间大小 与字符串长度有关。 3 Boolean(逻辑型、布尔型) Boolean类型的数据只可能有两个值:True(逻辑“真”)和False (逻辑“假”),用来表示“是”与“否”、“开”与”关”、 “对”与”错”这类只有两种取值的情况。一个逻辑型数据却要 占2个字节的存储空间。 4 Date(日期时间型) Date类型又称为日期型,这种类型的数据可以存放日期信息、时 间信息或者同时存放日期与时间信息。Date类型数据用8个字节来 表示日期和时间(公元100年1月1日~日) 。Object(对象型)和Variant(变体类型),将分别在后面节中讲解。 各种数据类型的直接常量1 字节型、整型、长整型: 十进制:1、20、500、-101 、230594 八进制:&O11、&O123 十六进制:&H11、&HFF2 精度浮点型: 普通记法:1.2、-1.4 科学记法:1.2E10、-1.23E-3错误:&O81 错误:&HFR错误:1.2E1.4、E4、12E3 逻辑型,只有两个取值:True、False4 日期型,使用“#”号作界定符: #1/1/2005#、#April 1, 2005#、#1:00:00PM# 5 字符串型,使用双引号“& &”: & Visual Basic & 、 &你好!& 特殊的字符串: & & & &表示一个双引号, & &表示空字符串。字符串常量中 的双引号必须成对出现。 变量变量:在程序执行过程中存储临时数据的命名内存单元。 变量名:程序是通过变量名来保存和访问相应内容单元中的值的。在VB中变量 名有如下规则:(1) 以字母开始,可以包括字母、数字和下划线;(2) 不能包含 标点符号;(3) 不能多于255个字符;(4) 不能与保留关键字重复(如:End、 Private、Sub) ;(5) 在同一作用域中,变量名不能重复。 变量的数据类型:数据类型决定变量占用内存的大小、数据处理的方式、表示值 的范围。 定义变量: Dim|Static|Private|Public 变量名 As 数据类型名 变量赋值:通过以下形式的语句为变量赋值。 变量名= 表达式 赋值语句的作用是把一个表达式的值赋予一个变量,即保存到变量所占的内存空 间。被赋值之后变量旧值被覆盖,变为新值。被赋的新值的类型和大小应与变量 的数值类型相一致,否则会出错。 另外,在过程、函数调用过程时,可以通过参数传递的方式为被调用过程中的变 量赋值。 引用变量的值:将变量名写到表达式中、过程函数实参表中,实际上就是对变量 的值进行引用。如下式中,是将变量b和c的值求和后赋给变量a。a 的值变为新 值,b和c的值被引用,并未改变。 a=b+c 变量的作用域 变量的作用域决定了一个变量在什么代码范围内可以被访问。 定义变量时使用的关键字以及定义变量的位置决定了变量的作用 域。 1、 过程级变量 也称为“局部变量”,在过程中定义,作用域为所在的过程。定义 过程级变量的方法有两种: (1) Dim 变量名 [AS 数据类型名] '动态局部变量 (2) Static 变量名 [AS 数据类型名] ?静态局部变量 如: Dim a As Integer 使用Dim关键字定义的局部变量只在定义它的过程执行时存在, 过程执行完变量即消失。下一执行该过程时,会重新生成变量,重 新初始化。 使用Static关键字定义的局部变量称为“静态变量”,它在整个 程序的运行过程都存在,但是只能被定义它的过程所用。每次执行 不重新进行初始化。可以在一个过程的多次执行之间保持其值。 2、模块级变量 在模块顶部的“通用声明段”中定义,在该模块中的所有过程中可 用。 定义的方法(两种方法等价) : (1) Dim 变量名 [As 类型名] (2) Private 变量名 [As 类型名] 如:Private d As Date Private S1 As String (定义变长字符串变量) Private S2 As String *4 (定义定义长字符串变量)一个定长字符串变量所占的内存空间是一定的,当其中的字符信息没达到 这个长度时,所剩的空间用户“空格“填充。如果给定长字符串变量赋一个超过 其长度的字符串,会被截掉多余部分,不会出现“溢出”错误。3、 应用程序级变量 也称为“全局变量”或“公共变量” ,在模块顶部的“通用声明段” 中使用Public关键字定义。全局变量在程序(即同一个工程中)的 所有模块中皆可用。 Public 变量名 [As 类型名] 如:Public p As Boolean 访问另一个模块中定义 的全局变量,应在变量名前 加模块名修饰。如 Form2.int1 = 2 在没有重名的情况下, 访问标准模块中的全局变量, 不必加模块名。一条语句定义多个变量 Public|Private|Dim|Static?变量1 [As 类型1][,变量2 [As 类型2]……] 每个变量都要指明类型,否则被定义为变体类型。例如,下 面语句定义了三个模块级变量,其中a和b是变体类型,c是整型: Private a, b, c As Integer 下面的语句定义的三个变量都是整型全局变量: Public a As Integer, b As Integer, c As Integer 变量的默认值 变量被定义之后,在第一次赋值之前,并不是没有值的,而 是具有默认值。 (1)数值型变量的默认值为0; (2)逻辑型变量的默认值为False; (3)日期时间型变量的默认值为#0:00:00#; (4)变长字符串变量的默认值为空字符串&&; (5)定长字符串变量的默认值是全部由空格组成的字符串,空 格个数等于定长字符串的字符个数; (6)对象型变量的默认值为Nothing; (7)变体类型变量的默认值为Empty。 强制变量定义 默认情况下,所有未出现过程的标识符,都被VB当成变体类型的 变量。这样,使得程序不容易调试,可以在模块声明段中加上: Option Explicit 使得所有的变量必须定义才能使用。 变量的赋值与取值 (1)变量的值除非被赋以新值,否则其值不会自动变化; (2)使用如下语句为变量赋值: [Set] 变量名=新值 赋以新值之后,旧值自动消失。 (3)对于数值类型变量,如果被赋的新值超出其可表示的范围, 会出现“溢出”错误; (4)将变量名写在表达式中,或给其他变量或属性赋值,或用 作过程或函数的参数,表示使用变量的值;打开【例3.1】使用过程级变量 打开【例3.2】使用模块级变量打开【例3.3】为模块级变量赋初值 变量重名问题 1.不允许同名的情况 一般情况下,在同一作用域内不能定义重名的变量。 (1)同一个过程中不能定义两个或更多的同名过程级变量,既 使类型不相同也不能同名。 (2)同一个模块中不能定义同名的模块级变量。 (3)同一个模块中不能定义同名的全局变量。 (4)同一个模块中的模块级变量和全局变量不能同名。 2.允许同名的情况 (1)不同的过程中可以定义同名的过程级变量。 (2)不同的模块中可以定义同名的模块级变量。 (3)过程中可以定义与模块级变量同名的过程级变量。 (4)过程中可以定义与全局变量同名的过程级变量。 (5)模块中可以定义与其他模块定义的全局变量同名的模块级 变量。 (6)不同的模块中可以定义同名的全局变量。 3.变量同名时的情况(1)不同作用域的变量同名时,作用域小的变量会屏蔽作用域 大的变量,即过程级变量屏蔽模块级和全局变量,模块级变量屏 蔽全局变量。例如,在例3.2中,按钮事件过程中的变量i屏蔽模 块级变量i,过程中被访问的i实际上是过程级变量。(3)如果不同模块中全局变量同名,访问其他模块中定义的全 局变量时应添加模块名进行限定(形式为“模块名.变量名”)。 访问本模块或标准模块中定义的全局变量时不必进行限定。如果 本模块与标准模块中的全局变量同名,访问标准模块中的全局变 量时也应加模块名进行限定。 (4)当全局变量与过程级变量同名时,在过程中直接使用这个 变量名时,指的是过程级变量。如果使用定义全局变量的模块名 来限定变量名,则可访问该全局变量。 (5)如果本模块中的模块级变量与其他模块中的全局变量同名, 可以在变量名前加模块名来访问全局变量。 对象型数据类型(Object)对象型变量占用4个字节共32位的内存空间,保存的是某一个对象的引用(即 内存中的地址),程序对对象型变量的操作等于对它所引用对象的操作。 对对象型变量赋值要用Set语句。对象型变量在被定义但未被赋值时的值是一个 特殊值:Nothing。例: Dim objFirst As Object (定义) Set objFirst= cmdOK objFirst.Caption =&OK& : objFirst.Move 120,234,345 Set objFirst=txtEdit : objFirst.Text=&Hello&Object类型的变量可以引用任何一种类型的对象。如果在使用中,一个变量只 引用一种特定类型的对象时,就可以将该变量定义为此特定类的对象型变量。 定义特定类型对象型变量,要使用对象的类型名,如已学习过的:Form、 Textbox、CommandButton、Line、Shape等。 例: Dim objSecond As CommandButton Set objSecond=cmdOK : objSecond.Caption=&Hello!& 注:对象型变量没有默认值,定义之后未赋值之前不能使用。特定类型对象型 变量只能引用同一类型的对象。 例: Dim objThird As Form Set objThird =cmdOK (错误!) 变体类型(Variant)变体类型变量可以存贮几乎所有系统定义类型的数据(除定长字符串和用户自 定义类型)。把其它类型的数据赋给变体变量,变体变量的类型会随之变化, 适应新的值。变体变量在存放数值时,占16字节的内存;存放字符串时,占用 22字节的内存(加字符串长度)。 例: Dim vntFirst As Variant (定义) vntFirst=“17” (为字符型“17”) vntFirst=vntFirst-15 (为数值型,值为 2) 变体变量类型是默认类型,在定义变量时可以省略“As Variant”。变体变量也可 以引用对象,赋值时须使用Set语句。 例: Dim vntSecond (定义) vntFirst=1234 (为数值型1234) Set vntFirst=cmdOK (对象型,对cmdOK的引用) Variant变量有三个的特殊的取值:Empty、Null。 1 Empty:一个变体变量可以在下列两种情况下具有Empty值:(1)尚未赋值 时;(2)被赋予Empty值之后。把Empty值赋给一个数值型变量时被理解为0, 赋给一个字符串时被理解为空字符“”。 2 Null:主要用于对数据库的操作,表示数据未知或数据不确定。Null值有如下 特点:(1)如表达式的任何一部分是Null,则整个表达式的值也为Null;(2) 把Null值作为参数传递给一个函数,则函数的返回值为Null。可给一个变体变量 赋值 Null。(3)Null与其本身不相等。 类型转换VB允许不同类型的变量之间相互赋值,也允许把不同类型的值赋予某种类型的 变量,VB会自动将所赋予的值转换为被赋值的变量的类型。 1 数值型变量的赋值 数据型变量之间可以相互赋值。浮点数转换为整型数时, 小数部分“四舍五入”为整数(其中0.5要向最近的偶数靠拢)。 2 字符串变量 如果字符串变量中存贮的是数值信息,则可以将其赋予数值型变 量。包括非数值字符的字符串(如有字母、标点符号)不能赋值给数值型变量, 否则出现“类型不匹配”错误。 3 逻辑型变量 逻辑变量的值赋给数值型变量,False转换为0,True转换为-1。 数值型变量的值赋给逻辑变量,0转换为False,其它值转换为True。 4 日期时间型变量日期时间型变量赋给数值型变量时,日期部分转换为数值的 整数部分,值为此日期距日的天数;时间部分转换为小数部分, 从零时到该时间占一整天的比例,12:00:00转为0.5。 例:dtm3=#3/18/:00# : sng2=dtm ?sng2的值为“36237.25” 5 所有的类型值均可以转换为字符串值。 日期时间型变量转换为字符串时,按照日期的短格式字符串。 可以使用类型转换函数进行显式转换。转换规则与上述默认转换相同。 变量的重名问题(1)同一个过程中不能定义同名的变量; (2)不同的过程中可以定义同名的变量; (3)同一模块中不能定义同名的模块级变量; (4)可以有与模块级变量、全局变量同名的过程级变量,在该过程中只能访问 过程级变量,即过程级变量会屏蔽同名的模块级变量或全局变量。 (5)在同一模块中不能定义同名的模块级与全局变量。 (6)不同的窗体模块中可以定义同名的全局变量,访问时须加模块名限定。 (7)多个标准模块中不能有重名的全局变量。 (8)在窗体模块中,窗体的属性、控件、过程和模块级变量是同一层次的,故 它们之间不能重名。 (9)过程中的局部变量比过程低一级,所以,与控件同名的局部变量会屏蔽控 件,如要访问该控件,要用窗体名来限定。 (10)在窗体模块中,要用窗体名来限时,窗体名都可以用关键字“Me”来代替。 在窗体模块中,如果没有重名,对窗体属性的修改、方法的调用可以省去窗体名 或“Me”的限定。 如:在frmFirst模块中如无变量、控件与窗体重名,frmFirst.Top=0 等价于 Top=0 定义变量要尽量避免重名;能定义小范围的变量就不要定义大范围的变量。 符号常量符号常量是指使用一个名称代表在程序运行过程中其值一直保持不变的量。 符号常量的作用有: (1) 便于记忆与识别,可使用一个具有描述性的名字替代一个抽象的值; (2) 便于修改,如果要改变常量所代表的值,只需在定义常量的地方修改即可。 常量的定义方法: (1) 过程级常量:在过程中定义 Const 常量名 [As 类型名]=表达式 (2) 模块级常量:在模块的声明段中 [Private] Const 常量名 [As 类型名]=表达式 (3) 全局常量:在标准模块的声明段中 Public Const 常量名 [As 类型名]=表达式 符号常量的命名规则与变量相同,一般使用con前缀或大写字母加以区别。 在程序运行过程中,不能再为符号常量赋值。例如,定义全局常量PI: Public Const PI As Double = 3.1415926 在过程中可以引用符号常量的值: s = PI *r *r 注意:不能在窗体模块和类模块中定义全局常量 。 第4章 运算符与表达式 运算符 “运算符”(Operator)是代表某种运算的符号。用运算符把变量 和常量连接起来形成“表达式”(Expression)。每一个表达式都 有一个值,即计算结果,称为表达式的值。 算术运算符 算术运算符对数值进行运算,计算结果也是数值。运算符 + * / \ Mod ^ 作用 加法运算 减法运算 取负数 乘法运算 除法运算 整除运算 求余运算 指数运算 示例 2+3 2-3 -1 2*3 5/2 5\2 5 Mod 2 2^3 结果 5 -1 -1 6 2.5 2 1 8 注1 2 3 4 5 6 7 8只用于整数 只用于整数 比较运算符比较运算符用来对两个数值的大小进行比较,如果满足运算符的 定义,则结果为True,否则结果为False。1 2 3 4 5 6 运算符 意义 & 小于 & &= &= = && 大于 小于或等于 大于或等于 等于 不等于 例子 2.5&5 2.5=5 3&5 3&5 3&=5 4&=4 4&=4 3&=5 2=4 4=4 4& &5 4& &4 结果 True False False True True True True False False True True False 字符串运算符字符串连接运算符+和& :将两个字符串首尾相连为一个字符串。 因为+号又是算术运算符,所以使用+号可能引发歧义。所以应 使用&进行字符串连接。&崇尚科学、& & &追求真知。& ' 运算结果为&崇尚科学、追求真知。& &团结献身& + &求是创新& ' 运算结果为&团结献身求是创新& &30& & &15& ' 运算结果为&3015& &30& + &15& ' 运算结果为&3015& 30 & 15 ' 运算结果为&3015&(先将整数转换为字符串) &30& & 15 ' 运算结果为&3015&(先将整数转换为字符串)字符串比较:字符串的大小是按字符顺序按字符的内码(ASCII 码和国标码)逐个进行比较。字符串的比较不是比较长度。例如:& ab & & & ac & (False), & ab & & & abc & (False), & ab & = & ab & (True), & ab & & & AB & (True), & 2000 & & & 400 & (False), &中& & “Zhong” (True)声明段中的Option?Compare?Binary|Text设置可以决定英文比较时是否考虑 大小写,Text时不区分大小写,Binary(默认值)时区分大小写。 字符串匹配运算符:Like字符串除了可以比较大小,还可以比较是否匹配。 strA Like strB strA和strB均为字符串表达式,其中strB为比较的“模板”。如果strA与strB定 义的模板相匹配,运算的结果为True,否则为False。 strB中可以包含任何字符,但是下列字符具有特殊含义: ? * # [charlist] [!charlist] 代表任何一个字符 代表任意多个字符,(包含0个) 代表任意一个数字,(0--9) charlist中包含的任何一个字符 不包含于charlist中的任何一个字符要匹配字符:[、?、#和*,要用方括号把它们括起来。]可以作为一个单独的 字符出现。如[]中的“-”出现在“!”号之后、最前或最后,则表示是一个可以匹 配的字符,在其它位置上时表示字符范围。 Like操作符的执行结果与Option Compare 语句的设定有关。默认情况下,设定 是Option Compare Binary,按照字符的表示的二进制数来比较的。如果在模块 的声明段加入Option Compare Text语句,则比较结果对大小字不区分。 例如: &aBBBa& Like &a*a& &F& Like &[!A-Z]& &aM5b& Like &a[L-P]#[!c-e]& &CAT123khg& Like &B?T*& &a& Like &[!abc]& &你& Like &[你我他]& &ABC& Like &AB[!ab]& &ABC& Like &aB[!ab]&True False True False False True True False&F& Like &[A-Z]” &a2a& Like &a#a& &BAT123khg& Like &B?T*& &[*?#]& Like &[[][*][?][#]]& &a& Like &[a!bc]& '当Option Compare Text时 '当Option Compare Binary时True True True True True 日期时间运算符 1.日期与数值的加减运算 表示在日期上加上或减去若干天。 2.日期与日期的减法 表示两个日期之间的天数差,不是整天则用小数表示。 3.日期的比较 比较晚的日期&比较早的日期。 对象型比较运算符 Is对象变量的比较运算符为:Is。如果两个被比较的变量引用的是同一个对象,则 得出True,否则为False。 例: Dim obj1 As Object '(定义一对象型变量 obj1) Dim obj2 As TextBox '(定义一对象型变量 obj2) Dim bln1 As Boolean '(定义一逻辑型变量 bln1) Set obj1=txt1 '(为对象型变量赋值) Set obj2=txt1 '(为对象型变量赋值) bln1=obj1 Is obj2 '(对象型变量的比较,结果赋予对象型变量) ?bln1的值为True 逻辑运算符对逻辑量进行运算的运算符称为逻辑运算符,包括:And、Or、Not、Imp、Eqv、 Xor共六个运算符。逻辑运算的结果也是逻辑值。 (1) And 逻辑“与”运算符:A And B 如果A与B是逻辑表达式(True或False),只要有一个为False,则运算结果为 False。二者全为True时,结果才为True。 (2 )Or 逻辑“或”运算符:A Or B 如果A与B是逻辑表达式(True或False),只要有一个为True,则运算结果为 True。二者全为False时,结果才为False。 (3) Not 逻辑“非”运算符: Not A Not 为单目运算符,如果A为True,则结果为False,如果A为False,则结果为 True。 (4)等价Eqv、蕴含Imp、异或Xor运算符的运算规则见下表。 逻辑运算的应用【例4.1】使用逻辑运算符。 打开【例4.1】 1 Private Sub Command1_Click() 2 Dim A As Integer, B As Integer, C As Integer 3 A = 10: B = 8: C = 6 ' 给变量赋值 4 Print A & B And B & C ' 结果为True 5 Print B & A Or B & C ' 结果为True 6 Print Not A & B ' 结果为False 7 Print B & A Eqv B & C ' 结果为False 8 Print B & A Imp C & B ' 结果为True 9 Print B & A Xor C & B ' 结果为False 10 End Sub 打开【例4.2】 【例4.2】根据给定条件编写表达式。 (1)假设a、b和c是三个变量。如果已知a&c,要判断b的值是否在a与c 之间,可以使用以下表达式: a & b And b & c 不能写成: a&b&c ' 错误 (2)如果不知道a和c哪个大,要判断b的值是否在a与c之间,可以使用 表达式: (a & b And b & c) Or (c & b And b & a) 【例4.3】如果变量x、y的值是平面上一个点的坐标(x,y),判断这个点是 否在第一象限内的表达式是: x & 0 And y & 0 判定(x,y)是否位于第一象限内单位圆中(单位圆是以坐标原点为圆心, 半径为1的圆),可以使用表达式: x & 0 And y & 0 And x * x + y * y & 1 判定(x,y)是否位于坐标轴上,可以使用表达式: x = 0 Or y = 0 编程验证上述表达式。创建工程,建立如图所示的界面,编写以下事件过程。 1 Private Sub Command1_Click() 2 Dim x As Single, y As Single 3 x = Text1.Text 4 y = Text2.Text 5 Text3.Text = x & 0 And y & 0 6 Text4.Text = x & 0 And y & 0 And x * x + y * y & 1 7 Text5.Text = x = 0 Or y = 0 8 End Sub 在窗体上面两个文本框中输入点的坐标,点击“判断”按钮,结果显示在下 面的三个文本框中。打开【例4.3】 按位逻辑运算如果逻辑运算的操作数(运算量)中有一个是数值型值。则VB会将所有 的运算量转换为整数进行“按位逻辑运算”。 运算规则是将整数以二进制形式按位进行逻辑运算,结果转换为十进行 制整数。 如: (1) 10 Or 8的值为10。10D= D = D= B(2) Not 10 的值为 -11。 10D= BOrNot -11D= B (补码取反加1) 表达式 表达式的求解顺序在一个表达式中,先计算优先级高的运算符,再计算优先级低的运算符。 优先级相同时,从左向右计算。 使用不括号,可以改变计算顺序,先计算括号内的。运算符的优先级如下表所示,在表达式中,先进行算术运算符,接着进行比较运算,然后才 进行逻辑运算符。所有比较运算符的优先级都相同;也就是说,要按它们出现的 顺序从左到右进行处理。 正确编写表达式1.将代数式转换为表达式 应遵循计算机语言的代码书写规范,免受代数知识的影响。 见表4.6。 2.浮点数的精度问题 无论是单精度还是双精度浮点数都有有效数字位数的限制, 无法准确表示超过该精度的值。在编程时,应考虑这一点。打开【例4.5】3.运算的顺序问题 有时,只要调整一下计算的先后顺序,结果就在不一样!4.运算过程中的溢出错误 避免出错运算过程中的溢出错误。 5.使用小括号 在表达式中加一些不影响计算顺序的小括号,会使表达式的 可读性增强。打开【例4.6】 表达式求值(1)已知变量a = 3、b = 4、c = 5,求下面表达式的值。打开【例4.7】 第5章 控制结构 Visual Basic提供的控制结构有以下四种: (1)顺序结构; (2)分支结构(也称为“选择结构”); (3)循结结构; (4)跳转结构。分支结构:If语句、Select Case语句; 循环结构:Do…Loop语句、For…Next语句、While…Wend语句; 跳转结构:GoTo语句、GoSub语句。 If 条件语句 单行形式的If…Then… 语句If 条件表达式 Then 语句块 False 条 件 True 语句块块行形式的If…Then… End If语句If 条件表达式 Then 语句块 End If这两种形式的If语句在执行流程方面是相同的。 如果“条件表达式”的值为 True ,则执行“语句块”,否则跳过“语句 埠”,直接执行随后的语句。 “语句块”可以是一条语句,多条语句。对于单行形式,多条语句必须使 用“:”隔开写在同一行上。 例:下面双种形式功能相同。 单行形式: If i Mod 2 = 0 Then Print &偶数& 块形式: If i Mod 2 = 0 Then Print &偶数& ' 语句块 End If 单行形式的If…Then…Else… 语句If 条件表达式 Then 语句块1 Else 语句块2 True 条 件False块形式的If…Then…Else…End If 语句语句块1If 条件表达式 Then 语句组1 Else 语句组2 End If 如果“条件表达式”的值为 True ,则执行“语句块1”;否则,执行“语句 块2”。“语句组1”与“语句组2”中至少有一组被执行,然后继续执行随后的语 句。 例: If i Mod 2 = 0 Then Print &偶数& ' 语句块1 Else Print &奇数& ' 语句块2 End If语句块2打开【例5.1】 If 语句的嵌套在 If 语句的“If语句块”和“Else语句块”中还可以包含另一个 If 语句。如: ……. If 条件1 Then ….. If 条件2 Then ….. Else …. End If …... Else ….. If 条件3 Then ….. Else …. End If ……. End If 【例5.2】判断输入数的奇偶性及所在的区间。 Private Sub cmd1_Click( ) Dim int1 As Integer, int2 As Integer : int1=Cint(txt1.Text) If int1&=0 Then txt2.Text=&请输入一个正整数!& Else int2=int1 Mod 2 If int2=0 Then If int1&100 Then txt2.Text=&这是一个大于100的偶数!& Else txt2.Text=“这是一个不大于100的偶数!& End If Else If int1& 100 Then txt2.Text=&这是一个大于100的奇数!& Else txt2.Text=&这是一个小于100的奇数!& End If End If 打开【例5.3】 End If End Sub 打开【例5.4】 If…Then…ElseIf…End If语句这是一种多重分支结构,比使用嵌套的If语句更容易理解。If 条件1 Then 语句块1 ElseIf 条件2 Then 语句块2 ElseIf 条件3 Then 语句块3 …… ElseIf 条件n Then 语句块n [Else 语句块n+1] End If打开【例5.5】从上到下,第几个条件表达式值为True,就执行相应的第几个语句块, 然后执行End If下面的语句。如果有不只一个条件表达式的值为True,只有最 上面的条件所对应的语句块被执行。如果所有条件表达式的值均不为True, 则执行Else关键字下面的“语句块n+1”,然后执行End If下面的语句。其中 Else和“语句块n+1”是可选部分。 注意:“ElseIf”关键字中间没有空格,不是“Else?If”。 Select Case 多重分支语句Select Case 测试表达式 Case 表达式1 语句块1 Case 表达式2 语句块2 …. Case 表达式n 语句块n [Case Else 语句块n+1] End Select Select Case语句中包含一个类型为数值或字符串的“测试表达式”,开始 时计算一次此表达式的值,然后用这个值与各个Case语句之后的“表达式X”比 较,如果二者匹配,则执行该Case之后的语句块,然后执行End Select之后的语 句。如果“测试表达式”中的值与“表达式X”中的多个相匹配,则只执行第一 个相匹配的Case之后的语句块。如果没有相匹配的,则执行Case Else之后的语 句。没有Case Else语句,则直接执行End Select 之后的语句。 关于“匹配”的定义Select Case语句中的“匹配”包括“精确相等”和“在指定区间内”两种情况。 具体使用的是哪种情况,由Case后面“表达式×”的给定方式决定。 Case后面“表达式×”的形式可以是以下4种情况之一: 1.单个常量、变量或表达式 如:Case 90和Case &Tom&。这种情况下,如果测试表达式的值与给出的值相 等就认为匹配。 2.使用关键字“To”连接的两个值 如:Case 1 To 5和Case &A& To &C&。这种情况下,关键字“To”连接两个值表 示值的范围(闭区间),如果测试表达式的值属于这个区间则认为匹配。 3.使用“Is”关键字、比较运算符和数值、字符串构成的表达式 如:Case Is &= 80和Case Is && &&。这种情况表示一个开区间,如果测试表达 式的值属于该区间便认为匹配。 4.以上三种的组合形式(使用逗号分隔) 如:Case 6, 8 To 9, Is &12。这种情况下,只要由逗号分开的多项中有任何一项 与测试表达式匹配,就认为匹配。打开【例5.6】打开【例5.7】 Do … Loop循环语句1 “当循环”的第一种形式: Do While 条件表达式 语句块 Loop 2 “当循环”的第二种形式: False 条 件 True 语句块 True 条 件 False语句块Do语句块 Loop While 条件表达式Do While …Loop形式 Do While …Loop形式两种循环共同的特点是:当每次计算“条件表达式”的值为True或非零数值时, 循环执行“语句块”;当“条件表达式”值为False或零值时,跳出循环,执行 Loop语句后别的语句。二者不同的是:第一种形式,如果条件表达式第一次计算 “条件表达式”就为False,则“语句块”不会被执行;第二种形式中,条件测试 在后,所以“语句块”至少被执行一次。打开【例5.8】 打开【例5.9】 3 “直到型循环”的第一种形式: Do Until 条件表达式 语句块 Loop 4 “直到型循环”的第二种形式: Do 语句块 Loop Until 条件表达式Do Until…Loop形式 Do …Loop Until形式True 条 件 False语句块 False 条 件 True语句块“直到型循环”与“当循环”不同点是:当每次计算“条件表达式”的值为 False或零数值时,循环执行“语句块”;当“条件表达式”值为True或非零值时, 跳出循环,执行Loop语句后别的语句。 “直到型循环”的两种不同形式的区别和“当循环”相同:第一种形式中的 “语句块”有可能一次都不被执行到;第二种形式中的“语句块”至少被执行一 次。打开【例5.10】 5 Do …Loop形式: Do 语句块 Loop 这种形式是一种“条件永远成立”的循环,需要使用Exit Do语句强制跳出 循环。Exit Do 语句Exit Do语句必须放置在Do…Loop语句的循环体中。执行到Exit Do时, 程序会立即结束循环,跳到Loop后面执行下面的语句。当有多个循环嵌套 使用时,Exit Do语句只跳出所在的最内层的Do…Loop循环。Exit Do语句不只可以用来结束不使用While和Until关键字的Do…Loop 语句,也可以用在使用了While或Until关键字的“当型循环”或“直到型循 环”中。如果在运行时发生了“死循环”,可以使用Ctrl+Break组合键返回调试 状态,再返回设计状态。打开【例5.11】 For … Next 循环语句For 计数器变量 = 起始值 To 终止值 [Step 增量] 语句块(循环体) Next [计数器变量] For Next 循环语句使用一个“计数器” 变量控制循环,这个变量不能是逻辑值或数组 元素,此语句每次自动给计算器变量增加一个 “增量”,如果变量的值超出给定的“终止 True 值”,则退出循环,否则会重复执行“语句 块”。第一次运行“语句块”时,只进行比较, 不改变变量的值。 当“增量”是正值或零时,变量的值大于 “终止值”时退出循环,当为负值时,变量量 的值小于“终止值”时退出。如果 “Step 增 量”省略,按增量为1处理。给“计数器变量” 赋以“初始值”“计数器变量”是否 超过“终止值”?False 循环体给“计数器变 量”增加“增 量”一般地,当事先可以确定循环次数时,使用For…Next语句,否则应使用 Do…Loop循环。打开【例5.12】 Exit For 语句就像使用Exit Do语句可以强制跳出Do…Loop循环一样,对于For…Next循 环,可以在循环体中使用Exit For语句,当程序执行到Exit For语句时立即终止 循环,跳到Next下面的语句继续执行。与Exit Do类似,Exit For语句只能用在 Exit For循环中,并且只能跳出所在的最内层For…Next循环。For…Next循环的“终止值”和“步长”问题特别值得注意的是,对于For…Next语句来说,一旦进入循环,其“终止 值”和“增量”便不会再改变了。例如,在下面的程序段中,循环的“终止 值”和“增量”是由变量j和k的值决定的。虽然在循环体中改变了这两个变 量的值,但是并不会影响循环次数(10次),“终止值”和“增量”仍然是 进入循环时两个变量的值,分别是10和1。 1 Dim i As Integer, j As Integer, k As Integer 2 j = 10: k = 1 3 For i = 1 To j Step k 4 Print i 5 j=j-1 6 k=k+1 7 Next 8 Print j, k 练习:分析下面程序段结束时窗体上显示的值是多少?(1) For i = 1 To 10 i2 = i2+1 Next (11) Print i (4) i2 = 1 For i = 1 To 10 i=i+1 i2 = i2 + 1 Next (11 6) Print i, i2 (6) i2 = 0 For i = 1 To 10 i2 = i2 + 1 If i & 6 Then Exit For Next Print i, i2 (7 7)(2) i2=0 For i = 1 To -2 Step -1 i2 = i2+1 Next Print i , i2 (-3 4)(3) i2=0 For i = 1 To 5 Step 2 i2 = i2+1 Next Print i (7)(5) i2 = 1 i3 = 10 i = 10 For i = 1 To i3 i=i+1 i2 = i2 + 1 i3 = i3 + 1 Next (11 6) Print i, i2(7) i2 = 0 i = 10 Do i2 = i2 + 1 Loop While i = i2 Print i2(1) 循环的嵌套(1)嵌套的层数不限; (2)内层控制结构必须完全位于外层的一个语句块中; (3)多个For…Next语句嵌套时,不能重复使用同一个“循环计数器变量”; (4)为了便于阅读与排错,内层的控制结构应向右缩进。 正确的嵌套:错误的嵌套: Exit Do和Exit For语句在循环嵌套时的作用Exit Do语句用于强制结束Do循环, 当有多个Do循环嵌套时,只跳出该语 句所在的最内层循环并执行对应Loop 之后的语句。同理,Exit For语句用于 强制结束For循环,当有多个For循环 嵌套时,只跳出该语句所在的最内层 循环并执行对应Next之后的语句。 当Do循环与For循环嵌套使用时, 如果Exit Do语句处于Do循环中的一个 For循环中,Exit Do语句同时会跳出 For循环。同理,如果Exit For处于一个 For循环内的Do循环中,程序不但跳出 当前的For循环,而且会跳出正在执行 的处于For循环内部的Do循环。 循环嵌套的执行流程当程序中有控制结构的互相嵌套时,其执行流程仍严格按照每个控制结构 既定的流程进行。下面以两重For…Next嵌套为例,演示循环嵌套时的执行流 程。多重嵌套的道理是相同的。 1 Private Sub Form_Click() 2 Dim i As Integer, j As Integer 3 For i = 1 To 3 4 Print &i=&; i 5 For j = 1 To 3 6 Print T &j=&; j 7 Next 8 Next 9 End Sub从这段程序的执行情况可见,外层循环执行一次(如i = 1),内层循 环要从头循环一遍(如j = 1、j = 2、j = 3)。 With 语句 在同一对象或同一个用户定义类型变量上执行一系列的语句。 With 对象名或自定义类型变量名 语句块(可以省略其中的对象名或变量名) End With With 语句可以对某个对象执行一系列的操作(如设置属性值、调用 方法),而不用重复指出对象的名称。例如: With cmd1 .Height = 2000 cmd1 .Height = 2000 .Width = 2000 cmd1 .Width = 2000 .Caption = &Hello& cmd1 .Caption = &Hello& .Move 0,0 cmd1 .Move 0,0 End With 注意: 一个With语句只能用于一个对象,如果一个对象属于另一个 对象,可以使用嵌套的With 语句。 不要跳入或跳出 With 块。如果在 With 块中的语句被执行,但是 With 或 End With 语句并没有执行,则会产生错误,或不可预知的 结果。 With语句的嵌套Private Sub cmd2_Click() Private Sub cmd2_Click() With Form1 .Height = 2000 .Width = 2000 .Caption = &Hello& .Move 0, 0 With .cmd1 .Height=1000 .Width=1000 .Caption=&OK& .Move 0, 0 End With End With End SubForm1.Height = 2000 Form1.Width = 2000 Form1.Caption = &Hello& Form1 .Move 0, 0 Form1.cmd1.Height=1000 Form1.cmd1.Width=1000 Form1.cmd1.Caption=&OK& Form1.cmd1.Move 0, 0End Sub 控制结构的应用【例5.15】求一元二次方程的根。 一元二次方程的根有下列三种情况: (1)当a=0、b=0时,方程无解; (2)当a=0、b≠0时,方程只有一个实根; (3)当a≠0时,方程有两个根(两个实根或两个虚根)打开【例5.15】打开【例5.16】 【例5.16】验证质数。 如果一个整数n只能被1和n整除,则n为质数。质数又称为素数,规定?1 不是质数,2是质数。本程序验证从文本框中输入的正整数是否为质数。 在窗体上的文本框txtInput中输入任一大于3的正整数n,然后单击按钮 cmdPrime,文本框txtOutput中显示出“n是质数”或“n不是质数”。 判断n是否为质数比较简单的方法是:用n逐个除以2~n-1之间的每个整 数,只要有一个可以整除,则说明n不是质数;如果全部不能整除,则说明n 是质数。 打开【例5.17】【例5.17】求水仙花数。 “水仙花数”是指一种三位整数,它各位数字的立方和等于该数本身。 编程将所有的水仙花数显示在窗体上,并在文本框中显示个数(水仙花数共 有4个:153、370、371和407)。 【例5.18】求Fibonacci(菲邦纳契)数列第n项的值。 已知Fibonacci数列为:1,1,2,3,5,8,……。该数列第一项和第二 项均为1,从第三项开始,每一项都是前面两项的和。打开【例5.18】除了数列的前两项之外,其他项可用迭代法求得。 【例5.19】使用级数求π的值。 根据下式,计算圆周率π的近似值,当计算到绝对值小于0.0001的通项时, 认为满足精度要求,停止计算。打开【例5.19】本例的两个重点是:(1)对于需要进行“无限次”计算的情况,如何利 用给定的“精度”在适当的时刻结束计算。(2)如何使程序编制得代码简单, 运行效率高。解法一: Private Sub cmdPi_Click() Dim a As Single Dim m As Single Dim n As Integer n=1 Do m = 1 / (2 * n - 1) a = a + (-1) ^ (n + 1) * m n=n+1 Loop While m &= 0.0001 Text1.Text = a * 4 End Sub 解法二: Private Sub cmdPi_Click() Dim a As Single Dim m As Single Dim s As Integer Dim i As Integer s=1 :i=1 Do m=1/i a=a+s*m i=i+2 s = -s Loop While m &= 0.0001 Text1.Text = a * 4 End Sub 【例5.20】将一角钱换成零钱(可以包括含1分、2分、5分中的任意多个面值), 共有多少种换法? 组成一角的零钱中,最多有10个1分、5个2分、2个5分。判断所有的组合中, 总和正好是一角(10分)的情况有多少次即为所求。这类方法称为“穷举法”, 也称为“列举法”。Private Sub Command1_Click() Dim i As Integer, j As Integer, k As Integer Dim n As Integer Print &1分个数&, &2分个数&, &5分个数& For i = 0 To 10 For j = 0 To 5 For k = 0 To 2 If i + j * 2 + k * 5 = 10 Then n=n+1 Print i, j, k End If Next Next Next Print &共有& & n & &种方法& End Sub打开【例5.20】 【例5.21】二分迭代法求一元方程的解。 用“二分迭代法”求解方程x3-x-1=0在区间[0,2]中的数值解(精度e = 10-6) (1)找 y=f (x) 的一个有根单调区间[a,b]; (2)选区间中点c=(a+b)/2,对区间[a,c]和[a,b]中的有根区间继续进行本操作; (3)当剩余区间足够小(满足某一给定精度)时,则认为区间的中点是方法的 数值解。Private Sub cmdCalc_Click() Dim x1 As Single, x2 As Single, x3 As Single x1 = 0 x2 = 2 Do x3 = (x1 + x2) / 2 If (x1 * x1 * x1 - x1 - 1) * (x3 * x3 * x3 - x3 - 1) & 0 Then x1 = x3 Else x2 = x3 End If Loop Until x2 - x1 & 0.000001 txtRoot.Text = (x1 + x2) / 2 End Sub打开【例5.21】 【例5.22】牛顿迭代法求一元方程的数值解。打开【例5.22】 【例5.23】矩形面积法求数值积分。打开【例5.23】因为多数函数f找不到其原函数F,可以编程求其数值解。定积分的几何意 义是求函数曲线和x轴、x = a、x = b三条直线所围成区域的面积(如图所示)。 位于x轴上方的面积是正值,x轴下方的面积是负值。 可将此区域分割成很多等宽度的矩形,用矩形的面积和近似表示区域的面 积。打开【例5.24】猜数字游戏 关于算法 “算法”是指通过编程解决问题的方法和步骤。对于Visual Basic来说,算法也包括工程中模块类型和数量、所采用的数据类 型、控制结构以及输入输出方式等。解决同一个问题一般有多种 算法。 评价算法优劣主要从三个方面考虑:(1)代码复杂度,指的 是程序代码是否精简易读,逻辑是否清晰;(2)空间复杂度,是 指程序中变量、数组等占用内存资源的大小;(3)时间复杂度, 是指程序运行所需时间。多数情况下,这三个方面是相互矛盾的, 应根据具体需要进行折衷处理。有经验的程序员可以设计出代码小、效率高、占用系统资源 少、便于理解、易于调试的算法。而初学者则需要经过一定的训 练、不断的实践才能达到这样的水平。 第6章 过 程 通用过程“过程”(Procedure)是VB程序中相互独立的程序块。每个过程有一定 的语法结构,可完成特定的操作。 使用过程,可将大的模块细分 。这样既简化了程序的编制,也使用程序 更易理解,便于调试。 VB的过程分为事件过程、通用过程和属性过程。事件过程由系统在一个 事件发生时自动调用,而通用过程必须在程序中需要的地方进行“显式”地 调用。 通用过程分为两类:(1)Sub过程、(2)Function过程。事件过程Sub过程(子过程) Function过程(函数)VB中的过程通用过程属性过程 (不在本课程范围内) Sub过程(子过程)定义Sub过程[Private | Public] [Static] Sub 过程名 [(形式参数)] 语句块(过程体) End Sub 过程语法结构的第一行称为首部。 (1)过程名:Sub过程的名称,与变量命名规则相同,在同一模块中不能重复。 (2)Public|Private :决定过程的作用域(全局的或模块级的),即可访问性 (默认值为Public)。 (3)Static:使该过程中所定义的所有变量均成为静态变量,不管在定义变量时 使用的是Dim或是Static。 (4)形式参数:过程可以有零个或多个参数,多个参数由逗号隔开。 (参数名1 [As 类型名],参数名2 [As 类型名],... ) 形参的命名规则与变量相同。在通用过程中,形参被看作是过程级变量,所 以不能在过程中定义与形参同名的变量。如果省略“As?数据类型名”,则默认 形式参数是变体类型的。 (5)过程体:多行语句,用来实现过程的功能。可以是空过程,不执行任何操 作。 “代码窗口”中过程的定义是平等的、并列的。 调用Sub过程(1)Call语句调用 Call?过程名(实际参数值1 , 实际参数值2 , ...) (2)使用过程名直接调用 过程名?参数值1 , 参数值2 , ... (如无参数,则不用括号) (不能使用括号)【例6.1】使用两种方法调用有参数的Sub过程。 打开【例6.1】 Private Sub ChangeForm2(intTop As Integer, intLeft As Integer, ?_ strCaption As String) ' 定义通用过程 Me.Top = intTop Me.Left = intLeft Me.Caption = strCaption End SubPrivate Sub cmd1_Click() Call ChangeForm2(0, 0, &VB&) End Sub Private Sub cmd2_Click() ChangeForm2 , &Visual Basic& End Sub' 第一种调用方法' 第二种调用方法 过程调用时的执行流程在程序的执行过程中,当一个过程(事件过程或通用过程)中有调用其他 过程的语句时,先暂停当前过程的执行(保留过程级变量的值,记录执行到的 位置),转到被调用的过程中继续执行。被调用过程执行完毕后(遇到End Sub语句或Exit Sub语句),返回调用它的过程从暂停位置继续向下执行。 (1)过程的嵌套调用 (2)调用时的参数传递 函数(Function 过程) 定义函数[Private | Public] [Static] Function 函数名 [(形式参数)] [As 返回值数据类型] 语句块(函数体) End Function 函数与Sub过程的主要区别在于有返回值,需要指定返回值的类型。 (1)指定函数的返回值:在函数体中为函数名赋值: 函数名=表达式 (2)函数的返回: 当遇到End Function 语句或函数体中的Exit Function语句则结果函数的执行, 返回到调用它的过程中继续向下执行。 (3) Exit Function: 它的功能与Exit Do相似,用于强制跳出所在函数。如果在函数返回之前未给函数名赋值,则返回一个函数类型的初始值,如0、 &&、#0:0:0# 或 False。 如果在返回之前多次为函数名赋值,则只返回最后的值。 调用函数因为Function过程包含了Sub过程的所有功能,所以调用Sub过程的方法也 可以用来调用Function过程。 1.Call语句调用 Call?函数名(实际参数1, 实际参数2, …) 2.函数名直接调用 函数名?实际参数1, 实际参数2, … 3.在表达式中调用 前两种方法都忽略了函数的返回值,一般较少使用。大多数情况下,把 函数用于赋值语句、表达式中或作为实际参数调用其他过程。这时使用函数 名调用并且必须加括号把实参括起来。例如: a = f() ' 函数f返回值用于赋值 b = f() + a ' 函数f返回值用于表达式计算 c = sub1(f()) + b ' 函数f返回值用于过程sub1的实际参数 当程序执行到有函数调用的过程时,先暂停当前过程,转而去执行被调 用的函数,函数执行完毕,将返回值返回,父过程使用返回值继续进行暂停 的运算和操作。 【例6.2】使用函数Factor计算10!-9!的值。Private Sub Command1_Click() Text1.Text = Factor(10) - Factor(9) End Sub'两次调用函数FactorPrivate Function Factor(n As Integer) As Long '计算阶乘的函数过程 Dim i As Integer, f As Long i = 1: f = 1 '变量赋初值 Do '计算阶乘 f=f*i i=i+1 Loop While i & n + 1 Factor = f '为函数名赋值,返回值 End Function 【例6.3】编程计算1~100之间质数的个数。 【例6.4】计算分数数列前n项之和(如图)。打开【例6.3】打开【例6.4】 【例6.5】已知下式成立(其中x的单位为弧度):编制名为mySin的函数, 要求它能够计算参数x(单位是“度”)的正弦值,精度为0.00001。Function mySin(x As Single) As Single Dim i As Integer, a As Single, s As Single x = x * 3.1415926 / 180 ' 角度转换为弧度 i = 1: s = x: a = s Do s = -1 * s * x * x / (i + 1) / (i + 2) ' 计算通项 a=a+s i=i+2 Loop Until Abs(s) &= 0.00001 mySin = a ' 返回值 End Function Private Sub Command1_Click() Dim x As Single x = Text1.Text Text2.Text = mySin(x) ' 调用mySin函数 End Sub打开【例6.5】本程序利用了通项之间的关系,每个通项都是由前一项计算得到,避免 了幂运算和求阶乘,使得算法比较优化。 【例6.6】使用欧几里德法求两个非负整数m和n的最大公约数。 欧几里德法被称为“辗转相除法”,用此方法求最大公约数的算法描述如下。 首先使用变量u和v分别保存m和n的值。然后当v不为0时,反复执行下面的三个操 作(其中r为一个辅助变量): 打开【例6.6】 r←u Mod v u←v v←r 直到v等于0时,变量u的值即为m和n的最大公约数。 下面的函数使用了欧几里德法,计算参数m和n的最大公约数并返回。 Private Function gcd(m As Integer, n As Integer) As Integer Dim u As Integer, v As Integer, r As Integer u=m v=n Do While v & & 0 r = u Mod v u=v v=r Loop gcd = u End Function 过程的参数传递方式在调用具有参数的Sub过程或Function过程时,实际参数传递给 形式参数的可以是值,也可能是其地址。一、按值传递参数(ByVal) 如果在定义通用过程时,形式参数名前加上关键字“ByVal”, 就规定了在调用此过程时,该参数是按值传递的。 按值传递时,传递给形参的是父过程中调用语句中相应实际 参数(可以是变量、常量或表达式)的值。 如果在子过程中改变了形参变量的值(比如给形变量参赋 值),不会影响父过程中实参的值。当子过程结束并返回父过程 后,实参还是调用之前的值。 如果通用过程中的形参设定为按值传递,不要求调用时相应 实参的类型与其一致,只要实参的值能够转换为形参的类型即可。 二、按地址传递参数(ByRef) 如果形式参数前加上关键字“ByRef”(默认设置),则该参数 是按地址传递的。调用时,传递给该形参的是父过程中调用语句中 相应实参(可以是变量或数组元素)的地址。即,子过程的形参与 父过程的相应实参共用了相同的内存单元。当在子过程中改变形参 的值时,同时也改变了父过程中实参的值。当子过程结束并返回父 过程后,实参变量的值已经发生了变化。 注意:按地址传递参数时,要求调用时使用的变量(或数组元 素)的类型与子过程相应的形参类型一致,否则出错。 如果实参是以下情况之一的,实际进行的是按值传递: (1)实参是常量;(2)实参是表达式;(3)实参是函数的调用; (4)实参是以括号括起的单个变量。在这四种情况下,实参的数 据类型可以与形参不同。 打开【例6.7】 【例6.7】检验参数的按值和按地址传递。 打开【例6.8】 【例6.8】以另一种方法求正弦值。 【例6.9】按地址传递的副作用。 打开【例6.9】 可选参数(Optional)打开【例6.10】Sub|Function?过程名(...,Optional?可选参数?[As?数据类型][=默认值],...)定义过程时在参数前加上关键字“Optional”。如果一个过程有多个参数,当 它的一个参数定为可选参数,那么它之后所有的参数都应用“Optional”定义为可 选的。还可以为可选参数指定默认值。 如果一个Sub或Function过程的某个参数定义为“可选参数”,则在调用此过 程时可以不提供该参数相应的调用值。以提供的默认值或数据类型的默认值传递。命名参数打开【例6.11】在调用通用过程时,如果使用以下方式在指定实参时同时指定形参名,则不 要求严格地按顺序指定。 形式参数名 : = 实际参数 过程的递归调用VB允许一个过程直接或间接地调用其自身,称为“递归”。递归是一种技 巧,可以将程序设计的非常紧凑,甚至有些问题必须使用递归来实现。但是, 如果程序设计得不好,递归调用的程序很容易出错。 尽管函数调用的是自身,但是每调用一次自己都会在内存中复制一份,因 此调用的次数越多,占用的空间越大。如果超过一定的限制,就会出错。 【例6.12】编写递归函数求阶乘n!。Private Function Fact(n As Integer) As Long If n & 1 Then Fact = n * Fact(n - 1) Else Fact = 1 End If End Function打开【例6.12】 父过程中调用: i = fact(3) 传递3 Sub fact(n As Integer) If n = 1 Then 返回6 fact = 1 n=3 Else fact = n * fact(n - 1) End If 传递2 End Function Sub fact(n As Integer) If n = 1 Then 返回2 fact = 1 n=2 Else fact = n * fact(n - 1) 传递1 End If Sub fact(n As Integer) End Function If n = 1 Then 返回1 fact = 1 n=1 Else fact = n * fact(n - 1) End If End Function 递归一般不能提高程序的执行性能,因为直接递归过程不断地调用其 本身,而间接递归会调用两个或更多的过程,这样对内存占用是巨大的, 所以,在递归过程中应尽量少用过程级变量和数组。下面使用递归计算Fibonacci数列的例子与使用循环计算相比,速度慢 得多。 【例6.13】编写递归函数计算Fibonacci数列第n项的值。 Private Function Fibo(ByVal n As Integer) As Long If n &= 1 Then Fibo = n Else Fibo = Fibo(n - 1) + Fibo(n - 2) '递归调用 End If End Function打开【例6.13】 第7章 数组与自定义数据类型 数组 数组概述数组是变量的扩展,一个数组可以存储多个值,通过数组名和下标对这 些值进行存取。 1.数组的优点 与变量相比,数组有以下优点: (1)数组能够保存多个值; (2)数组可与循环语句配合实现复杂算法; (3)数组可作通用过程的参数,传递大量的值; (4)数组可作函数过程的返回值,可返回大量的值; (5)数组常用来表示与一维、二维、三维空间分布相关的数据,非常直观; (5)动态数组可根据需要开辟内存空间,优化程序、提高效率。 2.数组的几个概念 (1)数组名(Array Name): (2)元素(Element): (2)下标(Index): (4)维数(Dimension): (5)下标的上界(Upper Boundary)和下界(Lower Boundary)。 常规数组Public|Private|Dim|Static?数组名(维数与下标界限)?[As?数据类型名] 常规数组,即固定大小的数组。由括号中的数值决定数组的维数和下标的上 下界。 1.指定下标界限 可以使用下列两种方式指定一维数组的下标界限: (1)使用关键字To指定下标的下界和上界,形式如下: Dim?a(m?To?n)?As?... m为下标下界,n为下标上界。m和n必须为整型常量,可以是负值,并 要求m≤n。 (2)只指定下标上界,由Option Base语句指定下标下界: Dim?a(n)?As?... 在模块“代码”窗口顶部的声明段中使用以下语句定义下标下界是0或1: Option Base?0|1 使用“0”时,上界n必须是非负整数常量,使用“1”时,上界n必须是正整数 常量。如果没使用Option Base语句,默认为0。 2.元素个数 一维数组元素个数的计算公式是: 元素个数=下标上界-下标下界+1 常规数组至少应该有一个元素,这时下标的上界与下界相等。 3. 访问数组元素 常规数组被定义之后,便具有了内存空间,可以通过以下方式访问数组 指定下标的元素: 数组名(下标) 访问数组元素时的“下标”可以是整型(或长整型)常量、变量或表达 式。下标值不能小于数组下标的下界,不能大于下标的上界,否则会引发“下 标越界”的运行时错误。 数组元素可以像普通变量一样被赋值、参与表达式计算、作为实参调用 通用过程,也可以使用循环语句对多个元素进行“批量”操作。 例子: Dim a(0 To 5) As Integer ' 定义数组a a(0) = 1 : a(1) = 3 : a(2) = 5 : a(3) = 7 : a(4) = 9 : a(5) = 11 ' 1:为单个元素赋 值 For i = 0 To 5 a(i) = 2 * i +1 Next ' 方法2:通过循环语句为个元素赋值 二维数组二维数组是指有两个下标的数组,每个下标对应一个“维”。定义二维数 组的语法格式为: Dim?数组名(第一维的下标界限 , 第二维的下标界限)?As?数据类型 二维数组中每一维下标界限的定义方式与一维数组相同。例子: Dim a(4 , 5) As Integer Public b(-5 To 5 , 10) As Double Private c(1 To 10 , 2 To 5) As Boolean 二维数组的元素个数是各维下标 取值个数之积。 二维数组可以被理解为二维表格。如 图所示,这是一个记录学习成绩的表 格,由行和列组成。可以使用以下语 句定义一个二级数组(如图所示)来 表示此表格: Dim a(1 To 3 , 1 To 4) As Integer (1)访问二维数组元素 a(i,j) = k (2)使用循环结构访问数组元素 多维数组多维数组是指三维或三维以上的数组,是在一维和二维概念上的扩展。多 维数组的定义、元素的访问方式与一维和二维数组类似。例如,下而定义的是2 个多维数组。 Dim a(3,3,4) As Integer ' 3维数组 Dim b(1 To 10,-4 To 5, 10,20) As Single ' 4维数组如果将二维数组比作二维表格,那 么,三维数组可看作是由多张二维表组 成的三维表格。 【例7.1】十进制数转换为二进制数。 Option Base 0 Private Sub Command1_Click() Dim i As Integer: Dim d As Integer Dim b(15) As Byte : Dim s As String d = Text1.Text ' 得到十进制数 Do Until d = 0 b(i) = d Mod 2 ' 除2取余 d=d\2 i=i+1 Loop Do While i & 0 i=i-1 s = s & b(i) ' 反序排列 Loop Text2.Text = s ' 显示二进制数 End Sub打开【例7.1】本程序使用的转换方法是“除2反序取余法”:把要转换的十进制数反复 乘以2取其余数(除尽为1,除不尽为0),直至商为0;再将余数反序排列即 为对应的二进制数。程序中使用了数组b保存每次除以2所得的余数。 【例7.2】找出数组元素中的最大值、最小值并计算所有元素的平均值。Option Base 1 Private Sub Command1_Click() Const N As Integer = 10 ' 定义常量 Dim a(N) As Integer ' 定义数组 Dim i As Integer Dim sum As Integer ' 此变量保存总和 Dim max As Integer ' 此变量保存最大值 Dim min As Integer ' 此变量保存最小值 For i = 1 To N a(i) = Rnd * 100 ' 为数组元素赋随机值 Print a(i) Next max = a(1) ' 注意!给变量赋初值 min = a(1) ' 注意!给变量赋初值 sum = a(1) ' 注意!给变量赋初值 For i = 2 To N If max & a(i) Then max = a(i) If min & a(i) Then min = a(i) sum = sum + a(i) Next Text1.Text = max ' 显示最大值 Text2.Text = min ' 显示最小值 Text3.Text = sum / N ' 显示平均值 End Sub打开【例7.2】 动态数组当在编程时不能预料应该为数组定义多少个元素时,可以使用Visual Basic 提供的动态数组。动态数组的维数和下标上下界可以在程序运行过程中改变。定义动态数组定义动态数组的的语法结构与定义常规数组相似,只是括号是空的: Public|Private|Dim|Static?动态数组名( )?[As?数据类型名] 定义语句确定了动态数组的名称、作用域和数据类型。在使用ReDim语句 重新定义之前,动态数组没有元素,不能使用。重定义动态数组重定义是指定动态数组的维数和下标界限(不能再改变数据类型): ReDim?[Preserve]?动态数组名([m1 To] n1[, [m2 To] n2,…]) ReDim语句指定动态数组维数和下标界限的方法与Dim定义常规数组相同。 对于同一个动态数组,重定义ReDim语句可以反复使用,即可以多次改变该动 态数组的维数和下标界限。Preserve关键字如果不加关键字Preserve,ReDim语句会清除重定义之前动态数组所有元素 中的数据,使用默认值来填充。如果希望重新定义之后,保留那些原来就有的 数组元素值,则必须使用Preserve关键字。
【例7.3】矩阵的转置。 矩阵是由N行M列数值组成的特殊数据形式,本例涉及的是方阵(即N=M, N称为阶数)。矩阵的转置是指行列数据交换(即沿对角线反转,如图)。 如图所示,矩阵A可以使用二维数组表示。打开【例7.3】 【例7.4】生成杨辉三角。打开【例7.4】杨辉是我国南宋时期的数学家,它引用前人 贾宪的研究成果提出了后人所说的“杨辉三角”。 如图7.9所示,杨辉三角的两侧全部是1,中间的 每个数是其左上方和右上方两个数之和。 数组函数与语句1.LBound函数、UBound函数 LBound(ArrayName[,Dimension]) UBound(ArrayName[,Dimension]) 参数ArrayName指定数组名,参数Dimension指定第几维,函数LBound返 回指定数组指定维的下标下界,函数UBound返回指定数组指定维的下标上界。 如果省略Dimension参数,则返回的是第一维的下界与上界。 2.IsArray函数 IsArray(VarName) 如果参数VarName是数组名,或是引用了数组的变体类型变量名,IsArray 函数返回True;否则返回False。未重定义的动态数组返回的也是True。如果 VarName是数组元素,返回False。 3.Array函数 Array(ArgList) 参数ArgList是由逗号分隔的多个值,Array函数将这些值组成一个一维变 体类型的数组。数组元素的值依次为各参数值。 4.Erase语句 Erase?数组名1[, 数组名2,…] Erase语句对数组进行初始化操作。对于常规数组,Erase语句使其成为数 据类型的默认值。对于动态数组,Erase语句释放动态数组的存储空间,要继 续使用这个动态数组,则必须使用ReDim语句重新定义。 数组作参数在编写通用过程时,允许定义数组参数,这样便可以使用一个参数传递大量 的值。 (1)数组形参的定义 [ByRef]?数组形参名()?As?数据类型名 数组形参名后必须加空括号,并且不能使用ByVal关键字修饰,因为数组参 数必须按地址传递。 (2)调用时,相应的实参必须是与形参相同类型的数组名,可以带空括号。 (3)一个通用过程可以定义多个数组参数。 (4)作参数的数组可以是任意维的,由实参数组决定。 因为是按地址传递,在通用过程中修改形参数组的元素值可以改变父过程中 实参数组的元素值。如果实参是动态数组,则相应的形参也可以被看作为动态数 组,在子过程中可以使用ReDim语句重新定义,改变数组维数、下标上下界以及 元素值,同时也改变了父过程的数组。【例7.6】使用数组参数编写求和的函数sum。 【例7.7】顺序查找。打开【例7.6】打开【例7.7】 【例7.8】折半查找。 “折半查找法”比顺序查找效率更 高一些。 折半查找的原理是:假设数组是递增 的,并且被查找的数一定在数组中。如图 所示,先拿被查找数(12)与数组中间的 元素进行比较,如果被查找数大于元素值, 则说明被查找数位于数组中的后面一半元 素中。如果被查找数小于数组中间元素值, 则说明被查找数位于数组中的前面一半元 素中。 接下来,只考虑数组中包括被查找数 的那一半元素。拿剩下这些元素的中间元 素与被查找数进行比较,然后根据二者的 大小,再去掉那些不可能包含被查找值的 一半元素。这样,不断地减小查找范围, 直到最后只剩下一个数组元素,那么这个 元素就是被查找的元素。当然,也不排除 某次比较时,中间的元素正好是被查找元 素。打开【例7.8】 不定数量的参数(ParamArray)如果通用过程的数组形参使用“ParamArray”关键字进行修饰,则该过程 被调用时可以接受任意多个普通实参值,这些实参值按顺序存于这个数组中, 在通用过程中可以访问这些值。 使用ParamArray参数有以下特点: (1)ParamArray关键字修饰的形参必须是通用过程的惟一的或最后一个形参; (2)一个过程只能有一个这样的形参。 (3)ParamArray不能与ByVal、ByRef或Optional关键字针对同一个形参一起使 用; (4)使用ParamArray关键字修饰的参数只能是Variant类型; (5)调用时,前面的实参传递给相应的形参,多余的实参都会以数组元素的 形式传递给ParamArray修饰的数组参数; (6)ParamArray修饰的数组参数只能是一维的。【例7.9】使用ParamArray求多个数之和。打开【例7.9】 函数返回数组函数返回数组是返回大量值的好办法。如果在定义函数过程时,返回值类 型后加上空的小括号,表示此函数过程的返回值是一个数组。 Function?函数过程名(形参列表)?As?数据类型名() 1.指定函数的返回值 首先在函数体中定义一个与返回值类型相同的数组,把要返回的值赋给数 组的各个元素。在返回之前,把这个数组名赋值给函数名,则这个数组会作为 返回值返回。 2.调用返回数组的函数 调用返回数组的函数之前,先定义一个与函数返回值类型相同的动态数组 (不必重定义)或变体类型的变量;调用函数时,把返回值赋给定义好的动态 数组名或变量。通过动态数组或变体变量即可访问返回数组的元素。【例7.10】矩阵乘法。打开【例7.10】 自定义数据类型可以使用Type关键字来定义自定义数据类型。自定义数据类型是由已存在 的数据类型组合而成的。定义自定义数据类型,必须要在模块的声明段中进行。 [Public|Private]?Type?自定义数据类型名 成员名1?As?已有的数据类型名 成员名2?As?已有的数据类型名 成员名3?As?已有的数据类型名 … End?Type 使用Private关键字定义的模块级自定义数据类型,只能在本模块中使用; 使用Public关键字定义的全局自定义数据类型,可在程序的所有模块中使用。 如果省略了Public和Private关键字,默认是应用程序级。如果要定义全局的自 定义数据类型,必须在标准模块的声明段中定义,不能在窗体模块中定义全局 自定义数据类型。 自定义数据类型中的成员的定义方法类似于定义变量,只是省略了 Public|Private|Dim|Static关键字。成员可以是任何已有的数据类型,包括定长和 变长字符串以及已定义的其他自定义类型。如果是变体类型,必须使用“As Variant”显式定义。成员也可以是数组(包括常规数组和动态数组)。除非使 用To关键字指定下标的上下界,否则成员数组的下标下界总是0,不受Option Base 0|1设置的影响。 1.定义自定义类型的变量和数组 可以使用与基本数据类型一样的语法格式来定义自定义类型的变量和数组。 例如: Dim student1 As Student, student2 As Student ' 定义两个Student类型的变量 Dim students(1 To 50) As Student ' 定义Student类型的常规数组students Dim mystudents() As Student ' 定义Student类型的动态数组mystudents Redim mystudents(50) ' 重定义动态数组 自定义类型变量所占用的内存空间是各个成员占用内存空间之和。其中变 长字符串和动态数组只占4字节,字符串和数组内容保存在内存的其他区域,成 员中保存的是这个区域的地址。 2.访问自定义类型变量或数组元素的成员 为自定义类型变量、数组元素赋值,或使用其值,应使用以下格式(类似 于访问对象的属性): 自定义类型变量名.成员名 自定义类型数组(下标).成员名 3.为自定义类型变量赋值 为自定义类型变量赋值有两种方法:(1)逐一给各个成员赋值;(2)使 用同类型的变量或数组元素为整个变量赋值,被赋值变量的每个成员的值与赋 值变量每个成员的值相同。 4.为自定义类型数组赋值 为自定义的数组赋值就是为其每个元素赋值,方法与为自定义类型的变量 赋值相同。 自定义数据类型参数如果通用过程的形式参数被定义为自定义数据类型,则可以给该通用过 程传递自定义类型的值。若父过程与被调用的子过程不在同一个模块中,必 须在标准模块中定义全局的自定义类型。 自定义类型参数必须按地址传递,不能使用ByVal关键字修饰。打开【例7.11】自定义数据类型返回值要让函数过程返回自定义类型的值,首先应定义全局的或模块级的自定 义数据类型。 定义函数过程时应该把函数返回值的类型定为该自定义类型。在函数过 程体中,定义自定义类型的变量,给这个变量的各个成员赋值,最后把这个 变量的值赋予函数名作为返回值(也可以把函数名当成这种自定义类型的变 量,直接给它的各个成员赋值)。打开【例7.12】 第8章 内部控件 直线(Line)控件Name:对象名。 X1,Y1,X2,Y2:直线控件的两个端点的坐标。 Visible:直线控件的可见性,True或False。 BorderStyle:直线的样式(0~6):透明、实线、虚线、点划线 ... BorderWidth:直线的宽度(单位为像素)。 Line控件无Move方法,要 移动它,可以改变它的四个端 点坐标属性的值。要隐藏直线 控件,可以把其BorderWidth属 性定为0(透明)或把Visible属 性设为Fasle,而不能设它的 BorderWidth属性为0。要应用除 “实线“与“透明“之外的直 线样式,线的宽度一定要设为1。 直线控件不能响应用户 操作,无事件过程,无Enabled 属性。 形状(Shape)控件Name:对象名。 Shape :该属性决定图形控件以什么形状显示(0~6)。矩形、正方形、椭圆、圆、 圆角矩形、圆角正方形。 Left、 Top、Width 、Height、Visible 属性与其它控件的意义相同。 BorderStyle:图形的边框样式(0~6):与直线控件一样为:透明、实线、虚线、 点划线 … BorderWidth:图形边框的宽度,单位为象素。 FillStyle:图形内部的填充样式(0~7):实心、透明、水平线、方格线 ... 形状控件有Move方法,用法与其它控件一样。与直线控件一样,形状控件 不能响应用户动作,无事件过程。打开【例8.1】 图像(Image)控件Name:对象名。 Left、 Top、Width 、Height、Visible、Enabled 属性与命令按钮的意义相同。 Picture属性:此属性决定图象控件中所显示的图象来 源。图象控件支持扩展名为:BMP、WMF、ICO、 JPG、GIF为扩展名的图象文件。在设计时可以通过属 性窗口来指定图象控件所显示的图象文件。在程序中 可以使用VB定义的LoadPicture方法来打开一个图象文 件赋予此属性。如: Image1.Picture=LoadPicture(&c:\bm.bmp&) 也可以使用不带参数的此方法使用图象控件不显示任 何图象,如: Image1.Picture=LoadPicture BorderStyle属性:0:无边框(默认);1:有边框。 Stretch属性:此属性为True时,当控件大小与图象的原 始大小不同时,会缩放图象来填充整个控件。注:当 图象缩放过度时,会造成失真。Image控件有Move方法,用法与其它控件一样。 Image控件有Click、DblClick事件,用法与其它控件一 样。 图片框控件(PictureBox)图片框具有图像控件的所有功能,还有如下功能 : (1)可作控件的容器; (2)支持绘图方法,可绘图; (3)通过Align属性定位于窗体的一侧。 Name:对象名。 Left、 Top、Width 、Height、Visible、Enabled 属性与命令按钮的意义相同。 Picture属性:属性的

我要回帖

更多关于 win7和win10内存占用 的文章

 

随机推荐