首页 VB程序设计第六章过程

VB程序设计第六章过程

举报
开通vip

VB程序设计第六章过程VB程序设计第六章过程VB程序设计第六章过程PAGEPAGE1VisualBasic6.0第PAGE1页共NUMPAGES33页VB程序设计第六章过程第六章过程主要内容函数过程的定义与调用子过程的定义与调用参数传递变量、过程的作用域递归常用算法(三)重点和难点6.1函数过程的定义与调用除了系统提供的内部函数、过程和事件过程外,用户还可自定义过程。在VB6.0中由用户定义(称自定义)的过程可分为以下几种:● 以“Sub”保留字开始的称为子过程;● 以“Function”保留字开始的称为函数过程...

VB程序设计第六章过程
VB程序 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 第六章过程VB程序设计第六章过程PAGEPAGE1VisualBasic6.0第PAGE1页共NUMPAGES33页VB程序设计第六章过程第六章过程主要内容函数过程的定义与调用子过程的定义与调用参数传递变量、过程的作用域递归常用算法(三)重点和难点6.1函数过程的定义与调用除了系统提供的内部函数、过程和事件过程外,用户还可自定义过程。在VB6.0中由用户定义(称自定义)的过程可分为以下几种:● 以“Sub”保留字开始的称为子过程;● 以“Function”保留字开始的称为函数过程● 以“Property”保留字开始的称为属性过程;● 以“Event”保留字开始的称为事件过程。引例[例6。1]已知多边形的各条边的长度,要计算多边形的面积.计算多边形面积,可将多边形分解成若干个三角形。计算三角形面积的公式如下:其中:x,y,z为三条边,c为三边和的一半。求三角形面积就可以编写一个函数过程,以后不论是求是么三角形,只要给出三边,就可象使用内部函数一样,使用这个自定义的求三角形面积的函数了。HYPERLINK”。。/.。/。。/../。./。./LocalFiles/_25B0_25EC_25B9_25AB/_25BE_25AB_25C6_25B7_25BF_25CE_25B3_25CC/_25D6_25D0_25D0_25C4_25C6_25C0_25BD_25A8/myvb/_25B5_25E7_25D7_25D3_25BD_25CC_25B2_25C4/ex6_1/lbc6_1.vbp"[例6.1]在myvb\vb6\ex6_1\lbc6_1。vbp'定义求三角形面积的函数过程PublicFunctionarea(x!,y!,z!)AsSingleDimc!c=1/2*(x+y+z)area=Sqr(c*(c-x)*(c—y)*(c-z))EndFunctionPrivateSubform_click()Dima!,b!,c!,s!DoDoa=val(InputBox(prompt:="输入一个边”,Title:="输入第一条边长",xpos:=2000,_ypos:=4000,Default:=3))LoopUntila〉0'预防按取消按钮和按转换后小于等于0的字符串Dob=val(InputBox(prompt:="输入一个边”,Title:="输入第二条边长”,xpos:=2000,_ypos:=4000,Default:=4))LoopUntilVal(b)>0‘对数值变量用val函数系统也不报错Doc=val(InputBox(prompt:="输入一个边",Title:=”输入第三条边长”,xpos:=2000,_ypos:=4000,Default:=5))LoopUntilVal(c)>0LoopUntila+b〉cAnda+c>bAndb+c>as=area(a,b,c)ClsPrint"第一条边长=”;a:Print”第二条边长=";b:Print”第三条边长=";cPrint"面积=";sEndSubPrivateSubForm_Load()Form2.Caption=”请单击窗体”EndSub2.函数过程的定义自定义函数过程有两种方法:(1)用“工具"菜单下的“添加过程”命令定义,生成一个函数的框架.操作如下:① 在窗体或模块的代码窗口选择“工具”菜单下的“添加过程”命令,显示“添加过程"对话框;② 在“名称”框中输入函数过程名(过程名中不允许有空格);在“类型”选项组中选取“函数”定义函数过程;在“范围”选项组中选取“公有的"定义一个公共级全局过程;选取“私有的”定义一个 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 模块级/窗体级的局部过程。③ 然后在过程模板中,就可以编写程序代码了.(2)利用代码窗口直接定义在窗体或标准模块的代码窗口把插入点放在所有过程之外,直接输入函数过程名。函数过程形式:[Static][Public][Private]Function函数过程名([参数列表])[As类型]局部变量或常数定义语句块函数名=返回值函数过程体[ExitFunction]语句块函数名=返回值EndFunction其中:⑴ 函数过程名的命名规则与变量名命名规则相同,但不要与VB中的关键字相同,也不要与WindowsAPI函数重名,还不能与同一级别的变量名重名.⑵ AS类型:表示函数返回值的类型,若缺省,则返回变体类型值。⑶ 参数列表形式:[ByVal]变量名[()][As类型][,[ByVal]变量名[()][As类型]…]参数也称为形参或哑元,只能是变量或数组名(数组名后则要加“()"),在定义时仅表示参数的个数、类型,但无值.ByVal表示该过程被调用时,参数是按值传递的,否则是按引用(地址)传递的。函数过程无参数时,函数过程名后的括号不能省略.⑷ 函数名=返回值在函数体内至少对函数名赋值一次.⑸ [ExitFunction]:表示退出函数过程(EndFunction的后继语句).⑹ Static表示为静态的,Public表示为全局的,Private表示为局部的。例6。2]要求定义MyReplace(S,OldS,NewS)函数过程,其作用同标准函数Replace一样。当调用MyReplace(”abcdefgabcdecd","cd”,”3")时函数的返回值为"ab3efgab3e3”。HYPERLINK”。。/。./。./.。/../。。/LocalFiles/_25B0_25EC_25B9_25AB/_25BE_25AB_25C6_25B7_25BF_25CE_25B3_25CC/_25D6_25D0_25D0_25C4_25C6_25C0_25BD_25A8/myvb/_25B5_25E7_25D7_25D3_25BD_25CC_25B2_25C4/ex6_2/lbc6_2.vbp”[例6。2]在myvb\vb6\ex6_2\lbc6_2。vbp'OptionCompareText比较不区分大小写字母,默认区分。本函数也受其影响PublicFunctionMyReplace(s$,OldS$,NewS$)AsStringDimi%,lenOldS%lenOldS=Len(OldS)’取OldS字符子串长度i=InStr(s,OldS)'在字符串中找有否OldS字符子串DoWhilei〉0’找到用NewS字符子串替换OldS字符子串s=Left(s,i-1)+NewS+Mid(s,i+lenOldS)i=InStr(s,OldS)’找下一个OldS字符子串LoopMyReplace=s'替换后的字符串赋值给函数过程名EndFunctionPrivateSubForm_Click()DimOriginal$,Part$,Chang$ClsOriginal=InputBox(prompt:=”输入原字符串”,Default:="abcdefgabcdecd",xpos:=2000,ypos:=4000,_Title:="第一个参数值”)Part=InputBox(prompt:=”输入被替换字符串",Default:=”cd",xpos:=2000,ypos:=4000,_Title:=”第二个参数值")Chang=InputBox(prompt:=”输入替换字符串",Default:=3,xpos:=2000,ypos:=4000,_Title:=”第三个参数值”)' 说明 关于失联党员情况说明岗位说明总经理岗位说明书会计岗位说明书行政主管岗位说明书 :调用了函数就使得参数的原来值发生了改变,因此必须注意保存才能正确显示。’当然用下面的方法不存在这个问题。Print”第一个参数值=";OriginalPrint"第二个参数值=”;PartPrint"第三个参数值=”;ChangPrint”替换结果值=";MyReplace(Original,Part,Chang)EndSub测试数据:假定S为“abcdefgabcdecd”,Oolds为“cd",News为”3”(“abcdefgabcdecd”,“cd”,“3”)第1次I=3结果“ab3efgabcdecd”(“ab3efgabcdecd”,“cd”,“3”)第2次I=9结果“ab3efgab3ecd”(“ab3efgab3ecd”,“cd”,“3”)第3次I=11结果”ab3efgab3e3”3。函数过程的调用函数过程的调用同标准函数调用,参与表达式运算,形式如下:函数过程名([参数列表])注意四点:① 参数列表,称为实参或实元,它必须与形参个数相同,位置与类型一一对应.可以是同类型的常量、变量、表达式,数组元素.② 调用时把实参的值传递给形参称为参数传递。其中值传递(形参前有ByVal说明)时实参的值不能随形参值的变化而变化,而引用传递(地址传递)的实参的值随形参值一起改变.③ 当参数是数组时,形参与实参在参数声明时应省略其维数,但括号不能省。④ 函数过程不能作为单独的语句加以调用,必须参与表达式运算。下面的程序段时对函数MyReplace的调用:PrivateSubCommand1_Click()Text1=MyReplace(Text1,"cd”,"3”)ST=“VisualBasic程序设计教程5.0版"PrintMyReplace(ST,"5。0”,"6.0")EndSub执行流程示意:Text1=MyReplace(Text1,"cd”,"3")PublicFunctionMyReplaec(S$,OldS$,NewS$)AsString6.2子过程的定义与调用(1)不是为了获得某个函数值,而是为了某种功能的处理。(2)要获得多个结果。为此VB提供了功能强大的而灵活的子过程。1.引例[例6。3]编写一个两个数交换的过程,供多次调用.Swap(x,y)子过程的定义主调程序调用Swap子过程PublicSubSwap(x,y)'未定义参数类型,系统默认为变体,因此,对于任何不同类型的两个数据都可以实现交换Dimtt=xx=yy=tEndSubPrivateSubForm_Click()'未定义参数类型,系统默认为变体.Dima,ba=10:b=20CallSwap(a,b)Print"a=";a,",b=";bEndSubHYPERLINK”。./../。。/.。/。。/。./LocalFiles/_25B0_25EC_25B9_25AB/_25BE_25AB_25C6_25B7_25BF_25CE_25B3_25CC/_25D6_25D0_25D0_25C4_25C6_25C0_25BD_25A8/myvb/_25B5_25E7_25D7_25D3_25BD_25CC_25B2_25C4/ex6_3/lbc6_3.vbp"[例6。3]在myvb\vb6\ex6_3\lbc6_3。vbp(程序有改动)2.子过程的定义[Static][Public][Private]Sub子过程名[(参数列表)]局部变量或常数定义语句[ExitSub]过程体语句EndSub注意五点:①ExitSub表示退出子过程,返回到调用程序的调用处。②把某功能定义为函数过程还是子过程,没有严格规定,但只要能用函数过程定义的,肯定能用子过程定义,反之不一定。当过程有几个值返回时,习惯上用子过程.③函数过程名有类型,在函数体内至少有一次对函数过程名赋值.子过程名没有值,过程名没有类型,在子过程体内不能对子过程名赋值。④形参是过程与调用程序之间交互的接口,从调用程序获得初值,或将计算结果返回给调用程序.⑤形参没有具体值,只代表了参数的个数、位置、类型;因此形参只能是变量,不能是常量、数组元素、表达式。3.子过程的调用子过程名[参数列表]或Call子过程名[(参数列表)](注:有参数列表必须可加上圆括号;无,加上也强行删去)[例6.4]分别编一计算某级数部分和的子过程和函数过程,并调用。级数为:用函数过程实现求部分级数的和用子过程实现求部分级数的和PrivateFunctionjishu1(x!,eps#)AsDouble'使用AsDouble和AsSingle结果有细微差别Dimt#,n%t=1:n=1:jishu1=0't每项的值,n项序DoWhileAbs(t)〉epsjishu1=jishu1+t:t=t*x/nn=n+1LoopEndFunctionPrivateSubjishu2(s#,x!,eps#)Dimt#,n%t=1:n=1:s=0’t每项的值,s各项总和,n项序DoWhileAbs(t)〉epss=s+tt=t*x/nn=n+1LoopEndSubHYPERLINK".。/.。/。./。。/。./。./LocalFiles/_25B0_25EC_25B9_25AB/_25BE_25AB_25C6_25B7_25BF_25CE_25B3_25CC/_25D6_25D0_25D0_25C4_25C6_25C0_25BD_25A8/myvb/_25B5_25E7_25D7_25D3_25BD_25CC_25B2_25C4/ex6_4/lbc6_4。vbp"[例6.4]在myvb\vb6\ex6_4\lbc6_4.vbpPrivateSubCommand1_Click()Dimf1#,f2#f1=jishu1(2#,0.000001)’调用函数过程,x的值为2,注意第一参数的类型匹配可以jishu2f2,2#,0.000001'调用子过程,求和解果放在实参f中ClsPrint:PrintPrint"调用函数求和结果=";f1PrintPrint"调用子过程求和结果=";f2EndSubPrivateSubForm_Load()Form2.Caption=”函数过程与子过程"EndSub6.3参数传递参数传递研究的是主调过程的实参与被调过程形参之间是如何传递的。6。3.1传址与传值传址:在形参与实参结合时,形参得到的是实参的地址,在形参值改变的同时也就改变了实参的值。也就是说同一地址,在主调和被调程序之间使用了不同的名字。因此,在传址方式下的实参只可以是变量而不能是常量,表达式。在定义过程时在形参变量前加上关键字ByRef则表示该参数是传址的(不加则系统默认为ByRef,即系统默认是传址的)。传值:形参得到的是实参的值,形参值的改变却不能改变实参的值。因此,这样的实参可以是变量,常量,表达式。在定义过程时在形参变量前加上关键字ByVal。[例6.5]两个变量的交换(使用传址和传址的演示)HYPERLINK".。/../。。/。。/。./../LocalFiles/_25B0_25EC_25B9_25AB/_25BE_25AB_25C6_25B7_25BF_25CE_25B3_25CC/_25D6_25D0_25D0_25C4_25C6_25C0_25BD_25A8/myvb/_25B5_25E7_25D7_25D3_25BD_25CC_25B2_25C4/ex6_5/lbc6_5。vbp"HYPERLINK”.。/.。/。./.。/.。/.。/LocalFiles/_25B0_25EC_25B9_25AB/_25BE_25AB_25C6_25B7_25BF_25CE_25B3_25CC/_25D6_25D0_25D0_25C4_25C6_25C0_25BD_25A8/myvb/_25B5_25E7_25D7_25D3_25BD_25CC_25B2_25C4/ex6_5/lbc6_5。vbp"[例6。3]在myvb\vb6\ex6_5\lbc6_5.vbpSubSwap1(ByValx%,ByValy%)‘传值t%=x:x=y:y=tEndSubSubSwap2(x%,y%)‘传址t%=x:x=y:y=tEndSubPrivateSubCommand1_Click()Clsa%=10。3:b%=20:‘在没有强制声明约定下,a%=10。3就是声明变量a是整型变量了,以后也不再能声明a为其他类型。Print"ByValbefore。。.”;”A1=";a,"B1=";bSwap1a,b'传值实参值并没有交换Print"ByValafter。。.";”A1=”;a,”B1=";bPrint;"—----—-————--——-—-—--—----—-—-—---"a=10:b=20Print”ByRefbefore。。。”;”A1=”;a,”B1=";bSwap2a,b’传地址实参值发生了交换Print”ByRefbefore。..”;”A1=";a,"B1=";bEndSub[例6.6]求若干个数的最大公约数.求若干个数的最大公约数的方法是:先求两个数的最大公约数,然后将这个最大公约数和第三个数再求最大公约数,如此下去.在求公约数的过程中,只要有一个最大公约数为1,就不要再往下求了.HYPERLINK".。/../../。./../。./LocalFiles/_25B0_25EC_25B9_25AB/_25BE_25AB_25C6_25B7_25BF_25CE_25B3_25CC/_25D6_25D0_25D0_25C4_25C6_25C0_25BD_25A8/myvb/_25B5_25E7_25D7_25D3_25BD_25CC_25B2_25C4/ex6_6/lbc6_6.vbp"[例6.6]在myvb\vb6\ex6_6\lbc6_6.vbpPrivateSubCommand1_Click()DimA()AsInteger,n%,m1%,m2%,mn%,i%Do’保证输入的串是一个大于等于2数字串n=Val(InputBox(prompt:=”求几个数的最大公约数?",Title:="输入",_Default:=4,xpos:=2000,ypos:=4000))LoopUntilVal(n)>=2ReDimA(1Ton)'重新定义数组Fori=1TonDo'保证输入的串是一个大于0的数字串A(i)=InputBox(prompt:="输入第"&i&”个数”,Title:="5796,5670,945,273",_Default:=5796,xpos:=2000,ypos:=4000)LoopUntilVal(A(i))〉0Nextim1=A(1)’求m1和m2的最大公约数Fori=2Tonm2=A(i)mn=gcd(m1,m2)Ifmn=1ThenExitForElsem1=mn'公约数为1停止计算NextiClsFori=1TonPrintA(i);Spc(2);NextiPrintPrint”它们的最大公约数为:”;mnEndSub’求最大公约数值传递PublicFunctiongcd(ByValm,ByValn)AsIntegerDimrAsIntegerIfm〈nThenr=m:m=n:n=rr=mModnDoWhiler<〉0m=n:n=rr=mModnLoopgcd=nEndFunction6.3。2数组参数的传递当参数是数组时只能通过传址方式进行传递.注意以下几点:在实参和形参中只能写数组名,忽略维数的定义,但一对圆括号在虚参中不能省略,而对于实参可写或不写圆括号。在被调过程中可通过Lbound和Ubound函数确定实参数组的下、上界。Lbound和Ubound函数的形式如:{L|U}bound(数组名[,维数])其中:维数指明要测试的是第几维的下标值,缺省是一维数组。例如:Dima(1To5,7To25)则下式可用LBound(a,1),UBound(a,1)求出a的一维下界和上界;而用LBound(a,2),UBound(a,2)求出a的二维的下界和上界。[例6。7]求和的值。编一函数tim,求任意一维数组中各元素之积。HYPERLINK"。。/。./../。。/../。。/LocalFiles/_25B0_25EC_25B9_25AB/_25BE_25AB_25C6_25B7_25BF_25CE_25B3_25CC/_25D6_25D0_25D0_25C4_25C6_25C0_25BD_25A8/myvb/_25B5_25E7_25D7_25D3_25BD_25CC_25B2_25C4/ex6_7/lbc6_7。vbp”[例6。7]在myvb\vb6\ex6_7\lbc6_7.vbpHYPERLINK”。。/.。/。./../../../LocalFiles/_25B0_25EC_25B9_25AB/_25BE_25AB_25C6_25B7_25BF_25CE_25B3_25CC/_25D6_25D0_25D0_25C4_25C6_25C0_25BD_25A8/myvb/_25B5_25E7_25D7_25D3_25BD_25CC_25B2_25C4/ex6_7/lbc6_7。vbp"HYPERLINK"../../。./.。/。./。。/LocalFiles/_25B0_25EC_25B9_25AB/_25BE_25AB_25C6_25B7_25BF_25CE_25B3_25CC/_25D6_25D0_25D0_25C4_25C6_25C0_25BD_25A8/myvb/_25B5_25E7_25D7_25D3_25BD_25CC_25B2_25C4/ex6_7/lbc6_7.vbp"PrivateSubCommand1_Click()Dima%(1To5),b%(3To8),i%,t1#,t2#CallInput1(a())'给A数组赋值CallInput1(b)'给B数组赋值t1#=tim(a)'求A数组的积t2#=tim(b())’求B数组的积ClsPrint"数组A各元素的值"Fori=1To5Printa(i);Spc(1);NextiPrintPrint"数组A的积=”;t1PrintPrint"数组B各元素的值”Fori=3To8Printb(i);Spc(1);NextiPrintPrint"数组B的积=";t2EndSubPrivateSubForm_Load()Form2。Caption="数组参数的传递"Command1.Caption="计算"EndSubPublicSubInput1(d()AsInteger)‘输入各个数组的值,Input是关键字Dimi%RandomizeFori=lbound(d)Toubound(d)d(i)=Int(Rnd*10)NextiEndSubPublicFunctiontim(e()AsInteger)AsDouble‘求各个数组的积Dimt#,i%t=1Fori=LBound(e)ToUBound(e)t=t*e(i)Nextitim=tEndFunction使用过程注意事项:1.确定自定义的过程是子过程还是函数过程函数过程名有值有类型,子过程名无值无类型.2.过程中形参的个数和传递方式的确定过程中参数的作用是实现过程与调用者的数据通信。(1)从主调程序获得初值,值传递。(2)将结果返回给主调程序,地址传递。3。实参与形参结合时对应问题个数、类型、位置、次序一一对应。形参是值传递时,对应实参可以是表达式、常量、数组元素。形参是地址传递时,对应实参只能是简单变量,否则,形参不能将其值传回到到调用程序中.数组、 记录 混凝土 养护记录下载土方回填监理旁站记录免费下载集备记录下载集备记录下载集备记录下载 类型、对象只能是地址传递.6。4变量、过程的作用域变量、过程随所处的位置不同,可被访问的范围也不同。变量、过程可被访问的范围称为变量、过程的作用域。6.4。1过程的作用域过程的作用域可分为:窗体/模块级和全局级1。窗体/模块级在定义的子过程或函数过程前加Private关键字的过程,只能被本窗体(在本窗体内定义的)或本标准模块(在本标准模块内定义的)中的过程调用。2.全局级指在窗体或标准模块中定义的过程,其默认作用范围是全局的,也可在Sub[Function]前加关键字Public.可供其所在 工程 路基工程安全技术交底工程项目施工成本控制工程量增项单年度零星工程技术标正投影法基本原理 中的所有窗体所有标准模块中的过程调用.但根据定义其过程所处的位置不同,其调用方式有所区别:(1)在窗体定义的过程,外部过程调用时,必须在过程名前加该过程所处的窗体名。(2)在标准模块定义的过程,外部过程均可调用,但过程名必须唯一,否则要加标准模块名。过程定义和调用的有关规则见下表6。4。2变量的作用域局部变量指在过程内用Dim语句(不可用Private,否则运行时出错)声明的变量(或不加声明直接使用的变量),它只能在本过程中使用,别的过程不可访问。局部变量随过程的调用而分配存储单元,并进行变量的初始化,在此过程体内进行数据的存取,一旦该过程体结束,变量的内容自动消失,占用的存储单元释放。不同的过程体内可有名字相同的变量,彼此互不相干。2.窗体/模块级变量指在“通用声明”段中用Dim语句或用Private语句声明的变量,可被所在定义的窗体/模块内的任何过程访问。3.全局变量指在“通用声明”段中用Public语句声明的变量,可被定义所在的工程内的任何过程或函数访问。全局变量的值在整个工程存在中始终不会消失和重新初始化。不同作用范围的3种变量声明及使用规则:说明:在窗体的通用声明段中用Public声明的变量,其实并不是全局变量,它只是告诉外部:“它是一个可以被存取的变量",所以在使用它时必须加上它所在的窗体名。若在不同级声明具有相同名字的变量,系统按局部、窗体/模块、全局次序访问.例如:窗体文件(Form1。frm)OptionExplicitPublicTempAsInteger’全局变量DimTTAsInteger’窗体级变量PrivateSubForm_Click()DimTempAsInteger’局部变量DimTTAsInteger'局部变量PrintForm1.Temp,Temp,TT’显示10000窗体级变量TT被屏蔽了Temp=10’访问局部变量TT=30'访问局部变量Form1。Temp=20’访问全局变量必须加窗体名PrintForm1.Temp,Temp,TT’显示201030EndSubPrivateSubForm_Load()Temp=100:TT=60‘给全局变量Temp赋初值TT和窗体级变量Debug.PrintTemp,TT’立即窗口显示10060EndSub6。4.3静态变量局部变量声明除了用Dim语句声明外,还可用Static语句将变量声明为静态变量。区别在于:Dim声明,随过程的调用而分配存贮单元并对其初始化;过程调用结束,变量的内容自动消失,存贮单元释放。Static声明,首次被调用分配存贮单元并对其初始化,过程调用结束,分配的存贮单元不释放,变量的内容继续保留被作为下次调用时的初值,直到工程结束。声明形式:Static变量名[AS类型]{Private|Public}StaticFunction函数过程名([参数列表])[As类型]{Private|Public}StaticSub子过程名[(参数列表)]过程名前加Static,表示该过程内的局部变量都是静态变量。[例6。9]一个由单击窗体事件过程(Form_Click())和一个求和函数(sum())组成的应用程序,在Form_Click()过程中5次调用sum()。HYPERLINK”。./.。/。./。./.。/。./LocalFiles/_25B0_25EC_25B9_25AB/_25BE_25AB_25C6_25B7_25BF_25CE_25B3_25CC/_25D6_25D0_25D0_25C4_25C6_25C0_25BD_25A8/myvb/_25B5_25E7_25D7_25D3_25BD_25CC_25B2_25C4/ex6_9/lbc6_9.vbp”[例6。9]在myvb\vb6\ex6_9\lbc6_9。vbpOptionExplicitPrivateSubForm_Load()Form2.Caption="单击窗体(静态变量,请修改函数Sum的头部)"EndSubStaticSubForm_Click()Dimi%,isum%StaticTim%'统计单击窗体次数Tim=Tim+1ClsPrint'Print”StaticFunction:1361015”Print"NoStaticFunction:12345”PrintSpc(4);Fori=1To5isum=Sum(i)Printisum;Spc(6);NextiPrint:Print”——--———-----—--—-—---——---————-—-—-———-—--—”PrintString(10,"")&"Click窗体"&Tim&"次"EndSubPrivateFunctionSum(nAsInteger)’PrivateStaticFunctionsum(nAsInteger)函数或过程内的所有变量均为静态变量,不管内部的变量是用Static或Dim定义的,都是静态的变量DimjAsInteger,K%’StaticjasInteger只有j为静态变量j=j+n:Sum=j:K=K+1Dubug.Print”k=”;k‘验证蓝字说法EndFunction6.5递归递归的概念用自身的结构来描述自身称为“递归”。例如:n!=n*(n—1)!(n-1)!=(n—1)*(n—2)!;sum(10)=10*sum(9),sum(9)=9*sum(8)2。递归子过程和递归函数VB允许一个自定义子过程或函数过程在过程体的内部调用自己,这样的子过程或函数称为递归子过程或递归函数。过程的直接调用(求y=3x2+9的值)SubCommand1_Click()……Callf1(y)EndSubSubf1(x)…x=f2(x)*3…EndSubFunctionf2(x)……f2=f3(x)+3EndSubFunctionf3(x)……f3=x*xEndSub过程的递归调用SubCommand1_Click()……Callf1(y)EndSubSubf1(x)…Callf1(y)EndSub[例6.10]编写求fac(n)=n!的递归函数HYPERLINK".。/。./。。/。。/.。/.。/LocalFiles/_25B0_25EC_25B9_25AB/_25BE_25AB_25C6_25B7_25BF_25CE_25B3_25CC/_25D6_25D0_25D0_25C4_25C6_25C0_25BD_25A8/myvb/_25B5_25E7_25D7_25D3_25BD_25CC_25B2_25C4/ex6_10/lbc6_10.vbp”[例6.10]在myvb\vb6\ex6_10\lbc6_10.vbpFunctionfac(nAsInteger)AsLong’递归求阶乘函数‘long型最多只能求12!,要求大阶乘可定义成Double型Ifn=1Thenfac=1Elsefac=n*fac(n—1)EndIfEndFunctionPrivateSubCommand1_Click()Dimn%Don=Val(InputBox(prompt:="输入阶乘数”,Default:=4,xpos:=2000,ypos:=4000))LoopUntiln〉0ClsPrintn&"!=”;fac(n)EndSub求Fac(4)的执行图:fac(4)=4*fac(3)—>fac(3)=3*fac(2)—〉fac(2)=2*fac(1)—〉fac(1)=1(递归)fac(4)=4*3*2*1〈—fac(3)=3*2*1<—fac(2)=2*1〈—(回溯)在递归处理中,用栈来实现。栈中存放形参、局部变量、返回地址。递推过程:每调用自身,当前参数压栈,直到达到递归结束条件。回归过程:不断从栈中弹出当前的参数,直到栈空.递归算法设计简单,但消耗的机时和占据的内存空间比非递归大。构成递归的结构的条件如下:递归结束条件及结束时的值;能用递归形式表示,并且递归向结束条件发展。[例6。11]利用递归求最大公约数HYPERLINK"../。./.。/。。/。。/.。/LocalFiles/_25B0_25EC_25B9_25AB/_25BE_25AB_25C6_25B7_25BF_25CE_25B3_25CC/_25D6_25D0_25D0_25C4_25C6_25C0_25BD_25A8/myvb/_25B5_25E7_25D7_25D3_25BD_25CC_25B2_25C4/ex6_11/lbc6_11。vbp"在myvb\vb6\ex6_11\lbc6_11。vbp递归结构:PublicFunctiongcd(mAsInteger,nAsInteger)AsInteger’求最大公约数If(mModn)=0Thengcd=nElsegcd=gcd(n,mModn)EndIfEndFunctionPublicFunctionpower(xAsSingle,nAsInteger)AsDouble’求幂,指数〉=0Ifn=0Thenpower=1Elsepower=x*power(x,n-1)EndIfEndFunctionPrivateSubCommand1_Click()Dimm%,n%,n1AsVariant,n2AsStringDon1=InputBox(prompt:="输入第一个数”,Default:=10,xpos:=2000,ypos:=4000)LoopUntiln1<>EmptyAndIsNumeric(n1)AndVal(n1)〉0m=n1Don2=InputBox(prompt:="输入第二个数”,Default:=4,xpos:=2000,ypos:=4000)LoopUntiln2〈>EmptyAndIsNumeric(n2)AndVal(n2)>0n=n2ClsPrintm&”,”&n&"的最大公约数是";gcd(m,n)EndSubPrivateSubForm_Load()Command1。Caption=”求最大公约数”Command2.Caption=”求幂”Form2.Caption="利用递归函数实现”EndSubPrivateSubCommand2_Click()DimxAsSingle,n%,x1AsVariant,n1AsStringDox1=InputBox(prompt:=”输入底数X的值",Default:=10,xpos:=2000,ypos:=4000)LoopUntilx1〈>EmptyAndIsNumeric(x1)x=x1Don1=InputBox(prompt:=”输入指数n的值”,Default:=2,xpos:=2000,ypos:=4000)LoopUntiln1<〉EmptyAndIsNumeric(n1)AndVal(n1)〉=0n=n1'自动具有四舍五入功能ClsPrintx&”的"&n&"次幂是”;power(x,n)EndSub分析以下子过程的功能,当n=100,r=8,输出结果是多少?PublicSubf(ByValn%,ByValr%)Ifn〉rThenCallf(n\r,r):Print"callf("&n\r&","&r&")"PrintnModr;EndSubPrivateSubCommand1_Click()ClsCallf(100,8):Print"callf(100,8)"EndSub运行结果是:1callf(1,8)4callf(12,8)4callf(100,8)执行流程示意:f(100,8)[print”callf(100,8)”]-〉f(12,8)[print"callf(12,8)"print4;]->f(1,8)[print"call(1,8)"print4;]—>print1;(递归图。红方框表示回溯时执行)回溯后可得上述运行结果。[例6。12]打印分形图(递归过程)。被分图形是等边三角形.HYPERLINK”。./../。。/。./.。/../LocalFiles/_25B0_25EC_25B9_25AB/_25BE_25AB_25C6_25B7_25BF_25CE_25B3_25CC/_25D6_25D0_25D0_25C4_25C6_25C0_25BD_25A8/myvb/_25B5_25E7_25D7_25D3_25BD_25CC_25B2_25C4/ex6_12/lbc6_12。vbp"[例6.12]在myvb\vb6\ex6_12\lbc6_12。vbpPrivateSubPicture1_Click()DimnAsIntegerDon=Val(InputBox(prompt:="输入三角形的层数”,Default:=3,xpos:=2000,ypos:=4000))LoopUntiln>1Andn<=10Picture1。ClsPicture1.Scale(0,600)-(600,0)'定义坐标系Picture1.CurrentX=0:Picture1.CurrentY=600Picture1。PrintTab(2);”递归n="&n&”时的图形"Calltriangle(30,320,570,30,570,n)EndSubPrivateSubtriangle(x1!,x2!,x3!,y1!,y2!,k%)‘作三角形Dimu1!,u2!,v1!,v2!Ifk〉1Thenu1=(x1+x2)/2u2=(x2+x3)/2v1=(y1+y2)/2Calltriangle(u1,x2,u2,v1,y2,k—1)Calltriangle(x1,u1,x2,y1,v1,k—1)Calltriangle(x2,u2,x3,y1,v1,k-1)ElsePicture1。Line(x1,y1)-(x3,y1)Picture1。Line(x1,y1)-(x2,y2)Picture1.Line(x2,y2)—(x3,y1)EndIfEndSub递归常见错误:递归调用出现“栈溢出”在递归调用时,其中的参数要向终止方向收敛。如下求阶乘的递归函数过程:PublicFunctionfac(nAsInteger)AsIntegerIfn=1Thenfac=1Elsefac=n*fac(n-1)EndIfEndFunctionPrivateSubCommand1_Click()Print“fac(5)=”;fac(5)Print“fac(—5)=”;fac(-5)‘栈溢出EndSub6.6常用算法(三)6。6.1数制转换[例6。13]将一个十进制整数m转换成r(2-16)进制字符串。方法:将m不断除r取余数,直到商为零,以反序得到结果HYPERLINK".。/../。./../。。/。。/LocalFiles/_25B0_25EC_25B9_25AB/_25BE_25AB_25C6_25B7_25BF_25CE_25B3_25CC/_25D6_25D0_25D0_25C4_25C6_25C0_25BD_25A8/myvb/_25B5_25E7_25D7_25D3_25BD_25CC_25B2_25C4/ex6_13/lbc6_13.vbp”[例6。13]在myvb\vb6\ex6_13\lbc6_13。vbpPrivateSubForm_Load()’在设计时同时选定几个对象,然后在属性窗口中设置FONT属性Label1。Caption="输入十进制数”Label2.Caption="输入r进制数(2—16)"Label3=”转换成?进制数"Command1.Caption=”转换”Form2.Caption="数制转换”Text1。Text=""Text2。Text=”"Text3.Text=""EndSubFunctionTranDec$(ByValm%,ByValr%)’转化数制函数,十进制数m转换成r进制数Dimimr%(60)’存放余数DimstrBaseAsString*16,strDtoR$,iB%,i%Ifm=0ThenTranDec=0:ExitFunction‘转换结束strBase="0123456789ABCDEF”'不同基数的位值数码i=0’imr下标从0开始DoWhilem<>0'累除求余imr(i)=mModrm=m\ri=i+1LoopstrDtoR=””i=i-1DoWhilei〉=0'求r进制数iB=imr(i)strDtoR=strDtoR+Mid(strBase,iB+1,1)i=i-1LoopTranDec=strDtoR'转换结果赋给函数EndFunctionPrivateSubcommand1_click()‘转换命令按钮Dimm0%,r0%,i%m0=abs(Val(Text1。Text))Text1.text=m0‘自动纠正成非负数r0=Val(Text2。Text)Ifr0<2Orr0〉16Theni=MsgBox(prompt:="输入的转换进制数超出范围",buttons:=vbRetryCancel+vbCritical,_Title:="范围在2—16之间")Ifi=vbRetryThenText2。Text="”Text2。SetFocusExitSub‘保证不再继续执行下面的部分了ElseEndEndIfEndIf'上面的程序段并不能阻止r0不在范围之内就必须正确输入后才能继续执行下面程序段Label3。Caption="转换成”&r0&”进制数"Text3。Text=TranDec(m0,r0)EndSub6.6。2加密和解密[例6。14]简单加密的思想是:将每个字母C加一序数K,式子c=chr(Asc(c)+k),例如序数k为5,这时“A”转换成“F",“a”转换成“f”,“B”转换成“G"…当加序数后的字母超过“Z”或“z”则c=hr(Asc(c)+k-26)。解密为加密的逆过程。HYPERLINK”.。/。。/.。/.。/.。/。。/LocalFiles/_25B0_25EC_25B9_25AB/_25BE_25AB_25C6_25B7_25BF_25CE_25B3_25CC/_25D6_25D0_25D0_25C4_25C6_25C0_25BD_25A8/myvb/_25B5_25E7_25D7_25D3_25BD_25CC_25B2_25C4/ex6_14/lbc6_14.vbp”[例6。14]在myvb\vb6\ex6_14\lbc6_14。vbpPrivateSubCommand1_Click()’加密加密常数为5DimstrInput$,Code$,Record$,cAsString*1Dimlength%,i%strInput=RTrim(Text1.Text)'获取需要加密的文本内容,然后加密length=Len(strInput)Code=""’存放加密了的串Fori=1Tolengthc=Mid(strInput,i,1)SelectCasecCase"a”To”z”c=Chr(Asc(c)+5)Ifc>"z”Thenc=Chr(Asc(c)—26)Code=Code+cCase"A”To"Z"c=Chr(Asc(c)+5)Ifc>"Z”Thenc=Chr(Asc(c)—26)Code=Code+cCaseElseCode=Code+cEndSelectNextiText2=Code'加密内容赋给文本Text2EndSubPrivateSubCommand2_Click()’解密DimstrInput$,Code$,Record$,cAsString*1Dimlength%,i%strInput=RTrim(Text2.Text)'获取加密文本内容,然后对其解密length=Len(strInput)Code=””'存放解密了的串Fori=1Tolengthc=Mid(strInput,i,1)SelectCasecCase”a”To”z”c=Chr(Asc(c)—5)Ifc<"a”Thenc=Chr(Asc(c)+26)Code=Code+cCase"A"To”Z”c=Chr(Asc(c)—5)Ifc<"A"Thenc=Chr(Asc(c)+26)Code=Code+cCaseElseCode=Code+cEndSelectNextiText3=CodeEndSubPrivateSubCommand3_Click()’清屏命令Text1="”:Text2="":Text3=”"EndSubPrivateSubForm_Load()Form2。Caption=”加密和解密”Text1="":Text2=”":Text3=””Text2.Locked=True:Text3.Locked=True'禁止修改文本框Text2和3的内容EndSub6.6。3查找顺序查找[例6.15]顺序查找根据查找的关键值与数组中的元素逐一比较,数组可无序。HYPERLINK"../。./.。/。./。./../LocalFiles/_25B0_25EC_25B9_25AB/_25BE_25AB_25C6_25B7_25BF_25CE_25B3_25CC/_25D6_25D0_25D0_25C4_25C6_25C0_25BD_25A8/myvb/_25B5_25E7_25D7_25D3_25BD_25CC_25B2_25C4/ex6_15/lbc6_15.vbp”[例6。15]在myvb\vb6\ex6_15\lbc6_15.vbpDima(1To20)AsvariantPrivateSubForm_Load()Dimi%RandomizeLabel1。Caption="数组中原有值”Label2。Caption="输入查找值"Label3.Caption="查找值在数组中的序号”Text1。Text=””:Text2.Text=””:Text3.Text="”Form2.Caption=”随机生成若干个数,顺序查找有无生成的数”Text2.TabIndex=0Text3.Locked=TrueText1。Locked=TrueFori=1To20a(i)=Int(Rnd*500)-120Text1.Text=Text1.Text&a(i)&”"NextiEndSubPrivateSubText2_KeyPress(KeyAsciiAsInteger)'输入查找值并调用查找过程Dimindex%IfKeyAscii=13Then’按回车键条件成立Text3.Text=””CallSearch(a,Text2.Text,index)‘调用查找Text3。Text=indexEndIfEndSubPublicSubSearch(a()asvarant,ByValkeyAsVariant,index%)'顺序查找过程Dimi%IfVarType(a(1))〈>vbStringThenkey=Val(key)'key成为数值型了'如果数组的值是数值型则必须将查找值也定成数值型,否则总是找不到Fori=LBound(a)ToUBound(a)Ifkey=a(i)Then’找到,元素的下标在index中,结束查找index=iExitSubEndIfNextiindex=-1’找不到,index形参的值为—1EndSub平均查找次数n/2二分法查找(使用此方法的条件是被查找的数组必须有序的,这里假定是从小到大排序了)思想:要查找的关键值Key同数组的中间(mid)项元素比较。首先令low=数组的下界值,hight=数组的上界值,mid=(low+high)\2当Key=a(mid)找到结束查找。否则当Key
本文档为【VB程序设计第六章过程】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
个人认证用户
知识改变命运的轨迹
Java开发工程师
格式:doc
大小:546KB
软件:Word
页数:34
分类:
上传时间:2023-03-24
浏览量:2