zoukankan      html  css  js  c++  java
  • VB热点答疑(2016.5.11更新Q4、Q5)

    收录助教君在VB习题课上最常被问到的问题,每周更新,希望对大家有所帮助。

    Q1.如何让新的文本内容接在原来的内容后面/下一行显示?

    A1.例如,Label1.text原本的内容是"VB程序设计",现在要把"助教好帅"接到原来的内容后面,应该这样写

        

        还有缩写形式:

    Label1.text &= "助教好帅"

        与第一种写法等价。

        要换行显示怎么办呢?拼接上换行符vbCrLf就行了,换行符表示“在此处开始新的一行”。如:

    Label1.text &= "助教好帅" & vbCrLf

    Q2.(针对第四周作业)如何累计加班天数?

    A2. 首先要给大家讲一点基础知识,叫做“变量的作用域”。什么意思呢?每个Dim出来的变量,都是有自己的“活动范围”的,出了这个范围,这个变量就不存在了。

          举个例子:

          

          也就是说,如果你在一个Sub内部(也就是Sub到End Sub这两行之间的区域)定义的变量,出了这个Sub就无法访问了。如果你在Button2_Click这个Sub里也定义了一个变量a,那这个a和Button1_Click里那个a没有丝毫关系。打个比方,比如你单名一个“飞”字,但你姓唐,那以“姓”为作用域来划分的话,你就和《三国演义》里那个同样名叫“飞”的人区分开了,因为他姓张。

          来看下面这个问题:我想定义一个整型变量sum,初始值为0,每点击一次Button1时sum就加1,点击Button2则在Label1里显示Button1被点击了几次(也就是sum的值)。这怎么做到呢?

          显然,sum不能被Dim在任何一个Sub里,因为两个Sub都要用到。

          解决方法是,在“通用声明段”里声明sum。

         

        问题解决。我习惯性的把定义在通用声明段的变量(如上面的sum)称为“全局变量”,而把Sub内部定义的变量(如前面的a)称为“局部变量”。

        还有一个初学者常见的错误

        

       这样做的后果是什么?答案是,Sub里声明的局部变量会“屏蔽”同名的全局变量,按这种写法,在Button2_Click这个Sub里,能访问到的sum只能是Sub内部定义的那个sum,而不是全局的sum。

    Q3. 我写的这些代码,到底什么时候、按什么顺序运行?是一点那个三角型按钮就依次运行吗?

    A3. 这里又要给大家介绍一个概念,叫做“事件驱动”,什么意思呢?简单地说就是“有事就处理,没事就歇着”。VB就是典型的事件驱动型编程。

         我们写的代码,并不是在程序一开始运行时就被执行,而是要“等待时机”。在VB里,每个控件都有很多系统预定义好的事件,比如一次鼠标点击(click)、按一次键盘(keypress)、窗口加载完成(onload)、文本内容发生改变(textchange)等等。系统会监听这些事件,当这些事件发生时,系统会执行相应的代码来响应事件的发生。好比上课老师点名让学生回答问题,点到谁的名字,谁就起来回答,没被点到的人坚决不吭声,这就叫“点名驱动型课堂”。

           所以我们写代码的时候,其实是按照以下步骤来做的:

          1.选择要处理哪个控件上发生的事件,是button1上的?还是textbox1上的?

          2.选择要处理的事件类型,是点了下鼠标?还是按了下键盘?

          3.当做完选择之后,系统会自动给我们初始化一段代码,就是该事件触发时要执行的那个代码段的头和尾(Sub 和 End Sub),我们只需要在这个代码段内部写好我们的代码,每次当这个事件被触发时,这段代码就被执行一次

     

    当光标落在某个sub范围内时,上面的两个栏会自动显示这个代码段对应的是哪个控件的哪个事件。

    所以大家注意,你写的代码当且仅当相应的事件发生时才会被执行。而且,相应的事件每发生一次,这段代码就执行一次

    反例:下面这段代码不work,因为每一次KeyPress时,这段代码都会从count=0开始原原本本地执行一遍。

    要正确的初始化count值,应该在声明时直接初始化:Dim count As Integer = 0。

    最后,系统对一些控件的常用功能做了快捷设置,比如在设计界面,双击一个按钮,系统会自动把光标定位到处理click事件的代码段内。双击Textbox、Label又会如何呢?自己试下吧!

    Q4.数组的声明方法总结

    在VB中声明数组,只有两种方法,而且都必须符合“先声明后使用”的原则:

    (1)如果声明时知道自己的数组长度,比如10,那就直接在声明里写出来,例如:Dim a(9) As Integer

    (2)如果声明时不知道数组的长度,那就先声明一个最大下标为空的数组,然后在使用前必须用ReDim语句为它确定长度,例如:

           Dim a(),b As Integer

           b = Val(TextBox1.text) ‘数组长度从文本框获得

           ReDim a(b-1)

           ...  '使用a数组

    非要问为什么,那是因为a()这样的声明形式并没有为数组真正分配内存空间(因为程序也不知道该分配多少给数组),所以必须用ReDim为数组分配内存空间,然后才能使用它。

    :Dim n,a(n) As Integer 这样其实等效于Dim n,a(0) As Integer,因为在这个地方的n只是刚刚被声明还没有初始值。而且声明里的n是“一次性”的,以后n的值无论怎么变化,a的大小都不会跟着变。

    Q5.彻底弄懂子过程/函数的概念

    子过程/函数其实就是执行一个特定功能的一段代码,大家这学期其实已经用过很多函数了,比如UBound,Mid,Val,Math.abs等等。下面分几块来讲(因为子过程是VB特有的概念,在别的语言中一般只有函数,所以下文如无特殊说明,我就以“函数”指代VB中的函数和子过程。

    (1)形式参数(形参)和实际参数(实参)之辨

    这恐怕是对于初学函数的同学来说最挠头的问题了。来看一段代码

    Private Function func(ByVal a As Integer,ByVal b As Integer)
        Dim s As Integer
        s = (a + b)/( a * b )
        If( s> 10) Then
            Return 10
        Else 
            Return s
        End If
    End Function

     这是一个简单的函数。

     然后我们来调用这个函数:

    Dim v1,v2,v3,v4,s1,s2 As Integer
    ...
    v1 = 10
    v2 = 15
    ... s1
    = func(v1,v2) ... s2 = func(v3,v4) ...

    【前方高能!】才华横溢的猪脚将上面的定义及调用过程拟人化讲给你们听:

     VB公司成立了新的部门(函数)func,以下是公司CEO老V和即将上任的部门经理小B的聊天记录。

     老V:小B,你知道你部的工作任务吗?

     小B:当然啦!客户给我们两个数字,我把它们加起来,然后求它们的积,然后用和除以积,然后如果结果大于10那么……

     老V:你说得太绕了,我听不懂,给我换个清晰的说法!

     小B:好的老大,这是我们部门内部的工作流程——客户依次给我们两个整数,为了描述方便,下文里把它们称为“a”和“b”(这就是所谓的形参!),首先我们求(a+b)/(a*b)这样一个表达式的值,存放在一个部门内部制定的变量s里,然后如果s大于10,我们返回10给客户;s不大于10的话,我们就直接把s的值告诉客户。

     老V:很好,这下清楚多了。

    ...

    【---下面是调用过程---】

    客户甲:B经理,我这里有两个数字v1和v2(实参来了),麻烦你帮我算个结果出来。

    小B:好的。唔,我看一下,v1是10,v2是15。秘书,告诉员工,按照部门的工作流程,把a替换成10,把b替换成15就行了!催他们干活快点!

    ...

    客户乙:B经理,我这里有两个数字v3和v4(也是实参),麻烦你。。。

    小B:不麻烦,你把v3、v4的值依次告诉我手下的员工,他们自然知道怎么处理!

    【故事结束】

    看懂了吗?简而言之,“形参”只是一个“形式”,在制定规则时指代“此处应有一个xxx”,而这个xxx到底值为多少,制定规则(部门工作流程)时是不知道的,需要在调用函数时靠实际的参数(客户)传进来。

    (2) ByRef 和ByVal的区别

    这个应该很好理解。打个比方,ByRef就是传“原件”,ByVal就是传“复印件”。如果一个人(函数)需要你的身份信息,你可以给他身份证原件,也可以给他复印件,他若不做修改,那这两种方式没区别;但他若要修改你的名字,那就区别很大了:ByRef时,相当于在原件上修改了你的名字,你的身份证就真的被改了;ByVal时,修改发生在复印件上,你的身份证原件丝毫不受影响。

     (3) “返回值”的概念

    这个相当好理解。比如s=s+1这样一个语句,如果我们写成函数的形式,是这样的:

    '声明函数
    Private Function addOne(ByVal n As Integer)
        Return n+1
    End Function
    
    ...
    '调用函数
    s = addOne(s)

    这样应该看得很清楚了吧。

    未完待续

  • 相关阅读:
    python 获取在线视频时长,不下载视频
    python treeview 多线程下表格插入速度慢解决方法
    c#操作magick,magick.net
    油猴脚本-Tampermonkey-淘宝dsr过滤器(过滤非3红商品)
    python 基础小坑 0==False is True
    pyd 编译,简单命令cythonize
    python 调用Tesseract,dll模式,无需安装,绿色版
    list与set的查询效率,大量数据查询匹配,必须选set
    selenium 页面加载慢,超时的解决方案
    selenium 不打印chromedriver的日志信息
  • 原文地址:https://www.cnblogs.com/leegent/p/5312223.html
Copyright © 2011-2022 走看看