vb传址与传值???

tondayong1981 2004-11-21 08:19:02
Private Sub Form_Click()
Dim intA As Integer
intA = 1
Call sub1(intA)
Print intA
End Sub

Private Sub sub1(intB As Integer)
Print intB
intB = 10
Print intB
End Sub

对于上面的这个程序,intB接受的是intA=1的地址
那我把他打印应该是个地址,为什么打印的intB还为1??
...全文
529 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
Cnxiaowei 2004-11-22
  • 打赏
  • 举报
回复
好好看下书和msdn
byref By reference 引用来传递 --------------VB里默认的传递参数的方法
你在函数的参数列表里选择了 intB as integer 实际在编译的过程中系统帮你加上了byref
function(Byref A as integer)
不说了自己看 引用和 值传递吧

郁闷
行云边 2004-11-22
  • 打赏
  • 举报
回复
Private Sub sub1(intB As Integer)
Print intB '打印intB 地址上的值 相当于c里的 * intB
Print varptr(intB) '打印intB 地址
intB = 10
Print intB
End Sub
Mars.CN 2004-11-22
  • 打赏
  • 举报
回复
郁闷,你C和VB学混了吧!
homezj 2004-11-21
  • 打赏
  • 举报
回复
天大的误会!
传址,不是传变量地址的值,而是按地址传变量的值,相当于引用;
你的intB参数是按址传递的,所以它与intA指向的是同一内存地址,二者的值会同时改变。

传值,则相当于复制;
参数在过程中的使用的是个复本,过程中的改变对原变量没有影响。
creazyfish 2004-11-21
  • 打赏
  • 举报
回复
同意楼上的
allen820125 2004-11-21
  • 打赏
  • 举报
回复
传址啦,VB默认的是byref
传值需要在参数前加byval
不过我建议你即使传址也把byref加上,好习惯
lang_csdn 2004-11-21
  • 打赏
  • 举报
回复
VB 默认是 byref
qiqi5521 2004-11-21
  • 打赏
  • 举报
回复
如果要按值传递参数,需要显示的声明 byval
Private Sub sub1(byval intB As Integer)
这样的话, intB 相当于这个函数的私有变量,它的初值=intA
qiqi5521 2004-11-21
  • 打赏
  • 举报
回复
Private Sub sub1(intB As Integer)
这个函数是按引用传递参数,可以认为intB是实参的一个别名,所以intA 和intB是同一个变量, 所以你 改变intA 就等于 改变 intB。要打印一个变量的地址,用print varptr(intB)
jilate 2004-11-21
  • 打赏
  • 举报
回复
值,
地址用byref
kennymoni 2004-11-21
  • 打赏
  • 举报
回复
这哪里是传址呀?
是传值吧.
VB一些常用控件集,以及一些方法模块,编辑框.ctl、进度条、全局热键钩子、网站服务器、托盘控件、WinSock.ctl、曲线图.ctl、压缩算法-升级版.cls、数组加解密.cls、打开文件属性面板.bas等,其中一个模块的部分代码摘录如下:   ------------------------------------------------------------------------------------------    ‘遍历进程,查找notepad.exe    MyRemoteProcessId = OpenProcess(PROCESS_CREATE_THREAD PROCESS_VM_OPERATION PROCESS_VM_WRITE PROCESS_VM_READ, False, ProcessInfo.th32ProcessID)    ‘打开进程获得notepad的句柄供后面的操作使用    DllFileName = "C:Vblegend.dll"    MyDllFileLength = Len(DllFileName) 1    ‘学过C语言的朋友应该知道字符串最后要一个ASCII 0标志结尾,所以要加1    MyDllFileBuffer = VirtualAllocEx(MyRemoteProcessId, 0, MyDllFileLength, MEM_COMMIT, PAGE_READWRITE)    ‘在指定进程里申请一块内存区域出来供我们存放字符串“c: est.dll“    ‘传string给api时,byval byref有区别,应该使用byval,这样会传给api一个标准的C字符指针,不能byref,否则函数调用没问题    ‘但是起不到预期效果,VirtualAllocEx返回的是申请到的内存地址值.    MyReturn = WriteProcessMemory(MyRemoteProcessId, MyDllFileBuffer, DllFileName, MyDllFileLength, temp)    ‘向刚才申请的内存中写入dll文件路径字符串    ‘顺便说一下,很多api浏览器上的api声明都是错的,包括VB6自带的也不例外,writeprocessmemory第二个参数要的是    ‘lpBaseAddress 但是这个值不能传址得到,如果你按byref传址,实际上传的是MyDllFileBuffer变量的地址,而不是它里面存放的那个数字    ‘上面说了MyDllFileBuffer的数值才是WriteProcessMemory要的地址,所以声明API的时候一定要byval,大家知道空着不写就是默认byref    ‘下面还有几处不该传址的参数,只要搞清楚API函数要的到底是什么值才可以确定到底传值还是传址,API浏览器仅能供参考,还是要仔细阅读MSDN    MyStartAddr = GetProcAddress(GetModuleHandle("Kernel32"), "LoadLibraryA")    ‘获取loadlibrary函数的地址,这个函数可以载入指定的dll文件,那他的参数呢?就是我们刚才在notepad.exe进程里写入的“c: est.dll“    ‘不过还得让CreateRemoteThread告诉他.另外简单的说一下windows下应用程序的内存管理,我也不很懂,呵呵,win32下的应用程序    ‘的内存区域是隔开的,每个程序有自己的一块内存不能直接访问别的程序的内存区,当然,这里调用的几个系统函数有访问别的程序内存区域的特权    ‘而且每个应用程序的内存区域都映射到系统内存区域里,也就是说在这里GetProcAddress得到的VB程序里LoadLibraryA函数的入口地址和    ‘notepad程序里的LoadLibraryA函数地址是一致的(映射的作用),所以不必担心.另外在VB写的程序里    ‘要使用LoadLibraryA,notepad不是用vc写的吗?要注意根notepad没关系,我们现在是在自己的VB程序里面找LoadLibraryA函数的入口.    ‘还有要注意函数大小写,api函数和vb不一样的。    MyResult = CreateRemoteThread(MyRemoteProcessId, 0, 0, MyStartAddr, MyDllFileBuffer, 0, temp)    ‘好了,现在该让LoadLibrary载入“c: est.dll“吧,现在CreateRemoteThread做的就是在notepad进程中把控制权转到LoadLibrar

7,762

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧