3.byval与byref 【程序编程相关:ASP与ActiveX控件交互实战(三)】
一句话,varptr返回的是变量所在处的内存地址,也可以说返回了指向变量内存位置的指针,它是我们在vb里处理指针最重要的武器之一. 【推荐阅读:ASP与ActiveX控件交互实战(二)】´体会byval与byref 【扩展信息:给网站添加一个注册表 之 “类的应用” 】byval传递的参数值,而byref传递的参数的地址.在一般程序中我们很少关心两者的区别,就算是传递了参数地址,只要在代码中小心不出现赋值语句,也是没有影响的.但是在一些api的应用中,规定要byval应用的,典型的应用就是copymemory. sub testcopymemory() dim l as long l = 5note: copymemory byval varptr(l), 40000, 4 debug.print l end sub 上面标号note处的语句的目的,是将l赋值为40000,等同于语句l=40000,你可以在"立即"窗口试验一下,会发现l的值的确成了40000. 实际上上面这个语句,翻译成白话: ----------------------------------------------------------------- 就是从保存常数40000的临时变量处拷贝4个字节到变量k所在的内存中. ----------------------------------------------------------------- 现在我们来改变一个note处的语句,若改成下面的语句:note2: copymemory byval varptr(l), byval 40000, 4 这句话的意思就成了,从地址40000拷贝4个字节到变量l所在的内存中.由于地址40000所在的内存我们无权访问,操作系统会给我们一个access violation内存越权访问错误,告诉我们"试图读取位置0x00009c40处内存时出错,该内存不能为´read´". 我们再改成如下的语句看看.note3: copymemory varptr(l), 40000, 4 这句话的意思就成了,从保存常数40000的临时变量处拷贝4个字节到到保存变量k所在内存地址值的临时变量处.这不会出出内存越权访问错误,但k的值并没有变. 我们可以把程序改改以更清楚的休现这种区别:´看看我们的东西被拷贝到哪儿去了 sub testcopymemory() dim i as long, l as long l = 5 i = varptr(l)note4: copymemory i, 40000, 4 debug.print l debug.print i i = varptr(l)note5: copymemory byval i, 40000, 4 debug.print l end sub程序输出:
54000040000 由于note4处使用缺省的byref,传递的是i的地址(也就是指向i的指针),所以常量40000拷贝到了变量i里,因此i的值成了40000,而l的值却没有变化.但是,在note4前有:i=varptr(l),本意是要把i本身做为一个指针来使用.这时,我们必须如note5那样用byval来传递指针i,由于i是指向变量l的指针,所以最后常量40000被拷贝了变量l里. 希望你已经理解了这种区别,在后面问题的讨论中,我们会使用上述的概念.4.堆栈
对在子程序调用的过程中进行参数传递的概念与分析.一般在程序中,参数的传递是通过堆栈进行的,也就是说,调用者把要传递给子程序(或者被调用者)的参数压入堆栈,子程序在堆栈取出相应的值再使用,比如说,如果你要调用 messagebox(hwnd,lptext,lpcaption,utype),编译后的最终代码可能是:... 下一页