收藏 分享(赏)

第八章--子过程和函数过程#3.ppt

上传人:tkhy51908 文档编号:8011400 上传时间:2019-06-04 格式:PPT 页数:74 大小:1.33MB
下载 相关 举报
第八章--子过程和函数过程#3.ppt_第1页
第1页 / 共74页
第八章--子过程和函数过程#3.ppt_第2页
第2页 / 共74页
第八章--子过程和函数过程#3.ppt_第3页
第3页 / 共74页
第八章--子过程和函数过程#3.ppt_第4页
第4页 / 共74页
第八章--子过程和函数过程#3.ppt_第5页
第5页 / 共74页
点击查看更多>>
资源描述

1、第八章,Sub子过程和Fun函数过程,本章内容及要求,8.1 Sub过程的定义和调用 8.2 Function函数过程的定义和调用 8.3 参数传递 8.4 过程的嵌套和递归调用 8.5 变量及过程的作用域,(1)窗体事件过程 Private Sub Form_事件名(参数列表) 语句组 End Sub(2)控件事件过程 Private Sub 控件名_事件名(参数列表) 语句组 End Sub,8.1.1 事件Sub过程,8.1 Sub子过程的定义和调用,在VB中Sub子过程分为:事件过程和用户自定义过程,方法一: 通过 “工具”菜单中的“添加过程”命令,出现“添加过程”对话框,选择过程类型

2、(子过程、函数、属性、事件)及作用范围(公有的Public、私有的Private),单击确定后得到一个过程定义的结构框架(模板),如:,Sub子过程的定义-两种方法,8.1.2 用户自定义 Sub子过程定义,Public Sub Sort( ) End Sub,Public|PrivateStatic Sub 子过程名(形参表)语句组Exit Sub语句组 End Sub,方法二:直接在代码窗口中输入,例1: 编一个交换两个整型变量值的子过程。Private Sub Swap( X As Integer, Y As Integer)Dim temp As IntegerTemp=X X=YY=

3、Temp End Sub,例2:编写求阶乘的子过程。 Private sub fact(n As Integer,f as Double) Dim i As Integerf = 1For i = 1 To nf = f * iNext End sub,。,说明: (1)子过程名:命名规则与变量名规则相同。子过程名不返回值,而是通过形参与实参的传递得到结果,调用时可返回多个值 (2)形式参数列表:形式参数通常简称“形参”,仅表示形参的类型、个数、位置,定义时是无值的,只有在过程被调用时,虚实参结合后才获得相应的值。 (3)过程可以无形式参数,但括号不能省。 (4)参数的定义形式: ByValB

4、yRef变量名( )As 类型, ByVal表示当该过程被调用时,参数是按值传递的; ByRef表示当该过程被调用时,参数是按地址传递的,缺省时传址。,方法一: Call 子过程名(参数列表) 方法二:子过程名 参数列表 说明:(1)参数列表称为实参或实元,它必须与形参保持个数相同,位置与类型一一对应。(2)调用时把实参值传递给对应的形参。 其中值传递(形参前有ByVal说明)时实参的值不随形参的值变化而改变。而地址传递时实参的值随形参值的改变而改变。,8.1.3 子过程的调用,(3)当参数是数组时,形参与实参在参数声明时应省略其维数,但括号不能省。(4)调用子过程的形式有两种,用Call关键

5、字时,实参必须加圆括号括起,反之则不用加圆括号括起。实参之间用“,”分隔。 例:调用上面定义的Swap子过程的形式:Swap a,bCall Swap(a,b),在某个事件过程中调用已定义的阶乘的过程fact: Private Sub Command1_Click()Dim n As Integer, m As Longn = 5Call fact(n, m)Print m End Sub,Private Sub CmdOK_click()Call Swap(a,b)Swap a,b End Sub,Private Sub Swap(x%,y%)Dim temp%Temp=X X=Y Y=Te

6、mp End Sub,过程调用的执行过程:,Visual Basic函数分为内部函数和外部(自定义)函数,外部函数是用户根据需要用Function关键字定义的函数过程,与子过程不同的是函数名将返回一个值 。,8.2 Function函数过程的定义和调用,方法一: 通过 “工具”菜单中的“添加过程”命令,出现“添加过程”对话框,选择过程类型(子过程、函数、属性、事件)及作用范围(公有的Public、私有的Private),单击确定后得到一个函数定义的结构框架(模板),如:,Public Function Sort( ) End Function,8.2.1 Function函数过程的定义,Fun

7、ction函数过程过程的定义-两种方法,Public|PrivateStatic Function 函数名()As函数名=返回值 Exit Function函数名=返回值End Function,方法二:直接在代码窗口中输入,Function fact(n As Integer) As DoubleDim i As Integer, f As Doublef = 1For i = 1 To nf = f * iNextfact = f End Function,把例2阶乘的sub 子过程改为Function函数过程,说明: (1)函数名:命名规则与变量名规则相同。但不能与系统的内部函数或其它通

8、用子过程同名,也不能与已定义的全局变量和本模块中模块级变量同名。 (2)在函数体内,函数名可以当变量使用,函数的返回值就是通过对函数名的赋值语句来实现的,在函数过程中至少要对函数名赋值一次。 (3)AS类型:是指函数返回值的类型,若省略,则函数返回变体类型值(Variant)。 (4)Exit Function:表示退出函数过程,常常是与选择结构(If或Select Case语句)联用,即当满足一定条件时,退出函数过程。 (5)形参数列表:形参的定义与子过程完全相同。,调用形式如下:函数名(实参列表) 说明:在调用时实参和形参的数据类型、顺序、个数必须匹配。函数调用只能出现在表达式中,其功能是

9、求得函数的返回值。,8.2.2 函数过程的调用,调用阶乘的过程: Private Sub Command1_Click()Dim S As IntegerS = 5Print fact(S) End Sub,2009-03-29以下关于过程及过程参数的描述中,错误的是 A)过程的参数可以是控件名称 B)调用过程时使用的实参的个数应与过程形参的个数相同 C)只有函数过程能够将过程中处理的信息返回到调用程中 D)窗体可以作为过程的参数,课堂练习,2010-03-22下面是求最大公约数的函数的首部 Function gcd(ByVal x As Integer, ByVal y As Integer

10、) As Integer若要输出8、12、16这3个数的最大公约数,下面正确的语句是A)Print gcd(8,12),gcd(12,16),gcd(16,8)B)Print gcd(8,12,16)C)Print gcd(8),gcd(12),gcd(16)D)Print gcd(8,gcd(12,16),Visual Basic中不同模块(过程)之间数据的传递有两种方式:通过过程调用实参与形参的结合实现; 使用全局变量来实现各过程中共享数据。,1、形式参数是指在定义子过程和函数时,出现在Sub过程名或Function函数名后面括号内的变量,是用来接收传送给Sub过程或Function的数据

11、,形参表中的各个变量之间用逗号分隔。,8.3 参数传递,8.3.1 形式参数与实际参数,2、实际参数实际参数是指在调用Sub或Function时,出现在子过程名或函数名后括号内的参数,其作用是将它们的数据(数值或地址)传送给Sub或Function过程与其对应的形参变量。实参可由常量、表达式、有效的变量名、数组名(如A( ))组成,实参表中各参数用逗号分隔。,参数传递指主调过程的实参(调用时已有确定值和内存地址的参数)传递给被调过程的形参。参数的传递有两种方式:按值传递、按地址传递。形参前加“ByVal”关键字的是按值传递,缺省或加“ByRef”关键字则按地址传递。,8.3.2 传地址与传值,

12、传址: 形参得到的是实参的地址,当形参值的改变同时也改变实参的值。因为它们共用一个地址。 传值: 形参只得到的是实参的值,形参值的改变不会影响实参的值。因为形参并不知道实参的地址。,Sub Swap2(x%, y%)Dim Temp% Temp = x: x = y: y = Temp End Sub,Sub Swap1(ByVal x%, ByVal y%) Dim Temp% Temp = x: x = y: y = Temp End Sub,什么是传址和传值呢?,传值,传址,传值,Private Sub CmdOK_Click()Dim a%,b%a = 10: b = 20Swap1

13、a, b 传 值Print “A1=“; a, “B1=“; ba = 10: b = 20Swap2 a, b 传地址Print “A2=“; a, “B2=“; b End Sub,Sub Swap2(x%, y%)Dim Temp% Temp = x: x = y: y = Temp End Sub,Sub Swap1(ByVal x%, ByVal y%) Dim Temp% Temp = x: x = y: y = Temp End Sub,值传递的执行过程如下图:,通过地址传递数据的执行过程,在子过程和函数过程调用时,如果实参是常量(包括系统常量、用Const自定义的符号常量)或表

14、达式,无论在定义时使用值传递还是地址传递,此时都是按值传递方式将常量或表达式计算的值传递给形参变量。如果形参定义是按传地址方式,但调用时想使实参变量按值方式传递,可以把实参变量加上括号,将其转换成表达式即可。,8.3.3 有关过程之间数据传递的几点说明,解决一个问题既可以使用子过程,也可以使用函数过程,是使用子过程还是使用函数过程呢?如果是需要求得一个值,一般情况使用函数过程,如不是为了求一个值,而是完成一些操作,或需要返回多个值,则使用子过程比较方便。,使用子过程还是使用函数过程?,Visual Basic中数组作参数是通过传地址方式传送。在传送数组时,除遵守参数传送的一般规则外,还应注意以

15、下几点:1为了把一个数组的全部元素传送给一个过程,应将数组名写入形参表中,并略去数组的上下界,但括号不能省略。 Private Sub Sort( a() As single) End Sub 其中形参“a( )”即为数组。,8.3.4 数组作为过程的参数,2被调过程可通过Lbound和Ubound函数确定实参数组的上、下界。 3当用数组作形参时,对应的实参必须也是数组,且类型一致。 4实参和形参结合是按地址传递,即形参数组和实参数组共用一段内存单元。 例如:定义了实参数组b(1 to 8),给它们赋了值,调用Sort()函数过程的形式如下: Sort b() 或 Call Sort(b()

16、) 实参数组后面的括号可以省略,但为便于阅读,建议一般不要省略为好。,课堂练习,Function FirProc(z As Integer,y As Integer,z As Integer) FirProc2x+y+3z End Function Function SecProc(x As Integer,y As Integer,z As Integer) SecProcFirProc(x,y,z)+x End Function Private Sub Command1_Click() Dim a As Integer,b As Integer,c As Integer a2:b3:c4

17、Print SecProc(c,b,a) End Sub A) 21 B) 19 C) 17 D) 34,课堂练习,2010-9-22以下关于局部变量的叙述中错误的是 A)在过程中用Dim语句或Static语句声明的变量是局部变量 B)局部变量的作用域是它所在的过程 C)在过程中用Static语句声明的变量是静态局部变量 D)过程执行完毕,该过程中用Dim或Static语句声明的变量即被释放,课堂练习,下列程序的输出结果是10 110。 Private Sub sub1(ByVal a As Integer, b As Integer)a = a + b: b = b + a End Sub

18、Private Sub Form_Click()Dim x As Integer, y As Integerx = 10: y = 20Call sub1(x, y)sub1 x, yPrint x; y End Sub,过程的嵌套:类似选择结构和循环结构的嵌套。也就是指一个过程中包含了另一个过程的调用。,8.4.1 过程的嵌套,8.4 过程的嵌套和递归调用,Sub form_click() Call sub1 End sub,Sub sub1 Y=F1(n) End sub,Function F1(x) F1=. End Function,过程的递归:简单说就是自己调用自己。,8.4.2 过

19、程的递归,Function fact(n %) As DoubleDim i As Integer, f As Doublef = 1For i = 1 To nf = f * iNextfact = f End Function,Function fact(n %) As DoubleIf n=1 thenfact=1elsefact=n*fact(n-1) End Function,用递归实现 阶乘,不用递归实现 阶乘,Function fact(n %) As DoubleIf n=1 thenfact=1elsefact=n*fact(n-1) End Function,现在假N=4,

20、观察 执行过程,Fact(4)=4*fact(3),Fact(3)=3*fact(2),Fact(2)=2*fact(1),Fact(1)=1,Fact(2)=2*1,Fact(3)=3*2,Fact(4)=4*6,注意,VB语言不允许过程的嵌套定义,即一个过程内不能包含另一个过程. VB语言允许过程的嵌套调用,即在调用一个过程的过程中,又调用另一个过程 .,窗体模块:文件扩展名为 .frm 窗体模块是VB程序的基础,与窗体对应,存放着该窗体的所有信息,如窗体及其上各控件对象的界面信息、属性、事件过程、通用过程、变量和常量的声明等。可以通过记事本打开查看。,8.5.1 窗体模块和标准模块,8.

21、5 变量及过程的作用域,标准模块:文件扩展名为Bas它们可以包含变量、常数、类型、外部过程和全局过程的全局(在整个应用程序范围内有效的)声明或模块级声明。写入标准模块的代码不必绑在特定的应用程序上,则在许多不同的应用程序中可以重用标准模块。当一个过程要被多个不同对象或不同模块中的程序调用时,那么该过程一般可放在标准模块中。,在VB中,由于可以在过程中和模块中声明变量,根据定义变量的位置和定义变量的语句不同,变量可以分为: 局部变量(过程级变量) 窗体/模块级变量(私有的模块级变量,能被本模块的所有过程和函数使用) 全局级变量(公有的模块级变量)。,8.5.2 变量的作用域,关于变量的生存期,变

22、量的生存期:是指变量的值能够保留多长时间,即分配给变量的存储空间能够被保留多长时间。1、 局部变量 Dim 声明的局部变量在本过程执行期间有效 Static 声明的局部变量在整个应用程序运行期间有效 2、 模块变量 在整个应用程序运行期间有效 3、全局变量 在整个应用程序运行期间有效,局部变量:在过程内声明的变量,只能在本过程中使用。,在过程内部使用 Dim 或者 Static 关键字来声明的变量,只在声明它们的过程中才能被访问或改变该变量的值,别的过程不可访问。所以可以在不同的过程中声明相同名字的局部变量而互不影响。,8.5.2.1局部变量过程级变量,例: Private Sub Form_

23、Load()Dim n%n= 10 End SubPrivate Sub From_Click()Dim n%Print “n=“;n End Sub,程序运行后单击窗体,其输出结果是什么?,局部变量,局部变量,窗体/模块级变量:在“通用声明”段中用Dim语句或用Private语句声明的变量,可被本窗体/模块的任何过程访问。但其他模块却不能访问该变量。 例如:在“通用声明”段声明如下变量Private s As StringDim a As Integer,b As Single,8.5.2.2 窗体模块级变量,全局变量也称公有的模块级变量,在窗体模块或标准模块的顶部的“通用”声明段用Publ

24、ic关键字声明,它的作用范围是整个应用程序,即可被本应用程序的任何过程或函数访问。 例如:Public a As Integer,b As single,8.5.2.3 全局级变量,3种变量声明及使用规则如下表:,全局变量与局部变量同名在不同过程中定义同名变量,它们互不影响,但若在一过程中定义使用了与全局变量同名的变量,则就应注意。,注意:当变量名相同而作用域不同时,将优先访问作用域小的变量。,8.5.2.4 关于多个变量同名,小,Public x As Integer 定义全局变量 Private Sub Form_Load()x = 1 将全局变量x 的值设置成 1 End Sub Pri

25、vate Sub Command1_Click()Dim x As Integer 定义局部变量x = 2 将局部变量x的值设置成 2Print “x=“; x Print “x=“; Form1.x End Sub Private Sub Command2_Click()Print “x=“; x End Sub,窗体将输出什么?,全局变量与全局变量同名如果不同模块中的全局变量使用同一名字,则通过同时引用模块名和变量名就可以在代码中区分它们。例如,如果有一个在 Form1 和 Module1 中都声明了公用的 Integer 变量 X,则把它们作为 Module1. X 和Form1. X

26、来引用便得到正确值。也就是说如果不同模块中的全局变量使用同一名字,引用时就需要使用“模块名.变量名”的形式来区分它们。,每次调用过程时重新分配存贮单元,初始化变量 过程调用结束后释放存贮单元,变量内容自动消失,动态变量与静态变量,动态变量,第一次调用过程时分配存贮单元,初始化变量 以后每次调用过程时不再重新分配存贮单元,变量保持上次调用结束时的值 过程名前加Static,表示该过程内的局部变量都是静态变量,静态变量(由static定义),Public|Private Sub 子过程名(形式参数列表)End Sub,Sub过程和Function函数既可写在窗体模块中也可写在标准模块中,在定义时可

27、选用关键字Private(局部)和Public(全局),来决定它们能被调用的范围。,8.5.3 过程与函数的作用域,1、窗体/模块级过程:加Private关键字的过程,只能被定义的窗体或模块中的过程调用。 2、全局级过程:加Public关键字(或缺省)的过程,可供该应用程序的所有窗体和所有标准模块中的过程调用。,按过程的作用范围来划分,过程可分为:模块级过程全局级过程,总结归纳过程的定义及作用域如下表,后面的内容请课后阅读,8.7 过程的嵌套和递归调用,8.7.1 过程的嵌套,在程序中调用一子过程,而在子过程中又调用另外的子过程,这种程序结构称为过程的嵌套。过程的嵌套调用执行过程如下图:,8.

28、7.2 过程的递归调用,用自身的结构来描述自身,称递归。例如,对阶乘的定义:,Visual Basic允许在一个Sub子过程和Function过程的定义内部调用自己,即递归Sub子过程和递归Function函数。,例 编求阶乘fac(n)=n! 的递归函数,Private Function fac(n As Integer) As IntegerIf n = 1 Then fac = 1Elsefac = n * fac(n - 1)End If End Function Private Sub Form_Click() Print “fac(4)=”;fac(4) End Sub,程序的递归

29、过程:,说明: 递归处理一般用栈来实现,分递推和回归两个过程,如上图所示。 递推过程:每调用一次自身,把当前参数(形参、局部变量、返回地址等)压入栈,直到递归结束条件成立。 回归过程:然后从栈中弹出当前参数,直到栈空。 递归算法设计简单,解决同一问题,使用递归算法消耗的机时和占据的内存空间要比使用非递归算法大。 使用递归算法必须要满足以下的递归条件:(1)存在递归结束条件及结束时的值;(2)能用递归形式表示,且递归向终止条件发展。,*8.8 过程的可选参数与不定数量参数,8.8.1 可选参数(Optional),概念:当然用户在自定义子过程或函数时也可以定义可选参数。要指定某个形参为可选参数,

30、这就是在形参变量前加入Optional关键字即可。如果一个过程某个形参为可选参数,则在调用此过程时可以不提供对应于这个形参的实参,若一个过程有多个形参,当它的一个形参被设定为可选参数,则这个参数之后面的其它参数也必是可选的,并且要用 Optional 关键字来声明。,例 可选参数的使用 Private Sub Nadres(x As String, Optional y As String)Text1.text= xText2.text= y End SubPrivate Sub Command1_Click () Dim strName As String Dim strAddress As

31、 String strName = “张 玉“ strAddress = “杭州市学院路85号“ 提供了两个参数。Call Nadres (strName, strAddress) End Sub,说明: 1、 检测可选参数是否被省略使用VB的内部函数IsMissing(可选参数名) 来测试过程被调用时,某个参数是否被省略。如果可选参数被省略了,则返回True,未省略,返回False。注意:若可选参数是其它类型,则IsMissing()总是返回False,不能起到检测的作用。,例: Private Sub Nadres(x As String, Optional y As Variant)Te

32、xt1.Text = xIf Not IsMissing(y) ThenText2.Text = yEnd If End Sub,2指定可选参数的缺省值也可以给可选参数指定缺省值。在下例中,如果未将可选参数传递到函数过程,则返回一个缺省值。 Sub Nadres(x As String, Optional y As String= “杭州市学院路85号“)Text1.text= xText2.text= y End SubPrivate Sub Command1_Click ()Dim strName As StringstrName = “张 玉“ 未提供第二个参数。Call Nadres

33、(strName) End Sub,8.8.2 使用不定数量的参数 一般说来,过程调用中的参数个数应等于过程说明的参数个数。可用 ParamArray 关键字指明,过程将接受任意个数的参数。,其定义形式如下:,Sub 过程名(ParamArray 数组名(),Function 函数名(ParamArray 数组名() As 数据类型,8.9 应用举例,8.9.1 查找问题,例 使用顺序查找法,在一组数中查找某给定的数x,算法设计:设一组数据存放在数组a(1)-a(n)中,待查找的数据放在x 中,把x与a数组中的元素从头到尾一 一进行比较查找。用变量p表示a数组元素下标,p初值为1,使x与a(p

34、)比较,如果x不等于a(p),则使p=p+1,不断重复这个过程;一旦x等于a(p)则退出循环;另外,如果p大于数组长度,循环也应该停止,则可由以下语句来实现它。,For P=1 to nIF a(p)=x then Exit For Next,下面编写一查找函数Find(),若找到x则返回下标值,找不到返回0Private Function Find( a() As Single, x As Single) As IntegerDim n%,p%,m%m=Lbound(a)n=Ubound(a)For P=m to nIF a(p)=x then Exit ForNextIf pn then

35、p=0Find=p End Function,例 使用折半查找法,在一批有序数列中查找给定的数x。,分析:设n个有序数(从小到大)存放在数组a(1)-a(n)中,要查找的数为x。用变量bot、top、mid 分别表示查找数据范围的底部(数组下界)、顶部(数组的上界)和中间,mid=(top+bot)/2,折半查找的算法如下: (1)x=a(mid),则已找到退出循环,否则进行下面的判断; (2)xa(mid),x必定落在mid+1和top的范围之内,即bot=mid+1; (4)在确定了新的查找范围后,重复进行以上比较,直到找到或者bot=top。,8.9.2 插入问题,例 把一个给定数插到有

36、序数列中,插入后数列仍然有序 分析:设n个有序数(从小到大)存放在数组a(1)a(n)中,要插入的数x。首先确定x插在数组中的位置p;(可由以下语句实现) ReDim Preserve a(n + 1) 让数组长度增加1,以便存放插入的数 p=1 do while xa(p) and p=n p=p+1 loop,a(p)a(n)元素向后顺移一个位置以空出a(p)元素放入x。(可由以下语句实现) for i=n to p step-1a(i+1)=a(i) next i a(p)=x,将其写成一插入函数 如下:,Private Sub Instert(a() As Single, x As S

37、ingle)Dim p%, n%, i%n = UBound(a)ReDim Preserve a(n + 1) 让数组长度增加1,以便存放插入的数p = LBound(a)Do While x a(p) And p = n 确定x应插入的位置p = p + 1LoopFor i = n To p Step -1a(i + 1) = a(i)Next ia(p) = x End Sub,2009-03-26以下关于函数过程的叙述中,正确的是 A)函数过程形参的类型与函数返回值的类型没有关系 B)在函数过程中,过程的返回值可以有多个 C)当数组作为函数过程的参数时,既能以值方式传递,也能以传址方

38、式传递 D)如果不指明函数过程参数的类型,则该参数没有数据类型,静态变量,除作用域之外,变量还有存活期,在这一期间变量能够保持它们的值。在应用程序的存活期内一直保持模块级变量和全局变量的值。但是,对于Dim声明的局部变量仅当过程执行期间存在,当一个过程执行完毕,它的局部变量的值就已经不存在,而且变量所占据的内存也被释放。当下一次执行该过程时,它的所有局部变量将重新初始化。,概念,局部变量的存活期由其定义的关键词来决定。,局部变量声明:Dim声明:随过程的调用而分配存贮单元,变量的初始化;过程体结束,变量的内容自动消失,存贮单元释放。Static声明,每次调用过程,变量保持上次调用结束时的值。声

39、明形式:Static 变量名 AS 类型Static Function 函数过程名(参数列表) As 类型Static Sub 子过程名(参数列表)注意:过程名前加Static,表示该过程内的局部变量都是静态变量。,例 有一个人编了下面一段程序,想用变量n记录单击窗体的次数。 Private Sub Form_Click()Dim n As Integern = n + 1Print “已单击次数:“; n & “次“ End Sub,分析程序运行后多次单击窗体的输出结果:,要记录单击窗体次数,如何实现?并比较使用模块变量和静态变量的差别。,Private Sub Form_Click()Di

40、m i% ,isum%For i = 1 To 5isum = sum(i)Print isum,Next iEnd Sub,Private Function sum(n As Integer)Dim j As Integer j = j + nsum = j End Function,1 2 3 4 5,Static j As Integer 结果如何?,补充例题:,2010-03-19下面关于标准模块的叙述中错误的是A)标准模块中可以声明全局变量B)标准模块中可以包含一个Sub Main过程,但此过程不能被设置为启动过程C)标准模块中可以包含一些Public过程D)一个工程中可以含有多个标准模块,课堂练习,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报