ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 3930|回复: 7

[讨论] 通过实例理解传址(byref,可省略)与传值(byval)的区别

[复制链接]

TA的精华主题

TA的得分主题

发表于 2015-6-23 08:26 | 显示全部楼层 |阅读模式
本帖最后由 yiyiyicz 于 2015-6-23 08:36 编辑

传址(byref,可省略,也称为引用)与传值(byval),实际应用中怎么选择,他们到底区别如何
这些东西要准确的说清楚,并不容易
以下示例代码,有助于理解这些概念
  1. Private Sub god(x As Integer, y As Integer, z As Integer)
  2.     x = 3 * z + 1
  3.     y = 2 * z
  4.     z = x + y
  5. End Sub

  6. Private Sub MainP()
  7. Dim x As Integer, y As Integer, z As Integer
  8.     x = 1
  9.     y = 2
  10.     z = 3
  11.     Call god(x, x, z)
  12.     Debug.Print x & " , " & y & " , " & z
  13. End Sub
复制代码

【问题】
看完代码后,先心算结果;然后再上机运算,看看你心算的结果和机器计算的结果是否一样
务必看清  Call god(x, x, z)
你能解释吗?

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-6-23 08:31 | 显示全部楼层
本帖最后由 yiyiyicz 于 2015-6-26 09:16 编辑

每一行代码都司空见惯,可第一次心算往往是错误的
解释如下
这段实例代码使用的传址方式。为了便于理解,先回顾一些基本概念
(一)参数传递的机制
参数传递,谁传递给谁?“主程序”调用“子过程”(sub)或者“函数”(function),以达到程序员想要实现的目的
主程序(一楼实例代码的MainP), MainP()中Call god(x, x, z)这句代码,就是调用子过程god,而(x, x, z)即为要传递的参数。有时(x, x, z)也称为实参表
“子过程”(sub)或者“函数”(function),也即一楼实例代码中Sub god(x As Integer, y As Integer, z As Integer)。
       (x As Integer, y As Integer, z As Integer),括号中三个参数代表要接收的参数。有时也叫形参表。
参数传递有两种方式:一种为【传址】,也就是Byref,通常可以省略;一种是【传值】,也就是Byval,不可以省略
这里,因为没有出现Byref,也没有Byval,所以采用的是传址,Byref省略了

接下来的问题就是:传址是怎么回事?传值又是怎么回事呢?
很学术的定义是这样的:
【传址】,主调程序将实参变量的的内存地址传给过程(子过程sub,或者函数function),而过程则通过内存地址访问实参
【传值】,把参数的数值传递给过程
咱们不是学计算机的,可以用土办法来理解这两个概念
【传址】,并没有直接告诉你参数的值,而是告诉你参数存放的地点。比如我让你取一本书,我告诉你的是这本书在书架第二层、左侧第三本书。而没有告诉你书名
【传值】,直接告诉你书名,在哪里你自己找。
用这种土法子,也有助于理解传值在调用中参数值不变,而传址则可以变。在传址的方法中,我只告诉你书在书架上的具体位置,而没有说书名。那么,我在这个位置放上《盗墓笔记》,则书(参数)就是小说《盗墓笔记》,如果放上一本《VBA入门》,那就是《VBA入门》。而传值方法,我直接告诉你的就是书名(参数值)---《盗墓笔记》,那么不管这本《盗墓笔记》是在书架上,还是厕所里,反正就是它了。

(二)计算过程
MainP过程中定义了三个变量x, y, z。分别为他们赋值1,2,3。调用时,将x的地址传给了子过程god的x和y这两个形参。实际上都是实参x的别名,对应的是同一个地址空间。
god在处理中对x和y值的更新,其实都是对实参x的更新。
具体处理过程如下


  • x(形参)← x(实参)← 1 :y(形参)← x(实参)← 1 :z(形参)← z(实参)← 3
  • x(形参) = 3 * z(实参已经通过形参赋值过) + 1 = 3*3+1 = 10
  • x(实参)← x(形参)← 10:之前的x(实参)=1 这时已经被覆盖了
  • y(形参) = 2 * z = 2*3 = 6
  • x(实参)← y(形参)← 6:之前的x(实参)=10 这时再次被覆盖
  • z(形参) = x(形参) + y(形参)= x(实参)+ x(实参)= 6+6 =12

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-6-23 08:51 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 yiyiyicz 于 2015-6-26 08:41 编辑

为了在实际当中应用,一些原则可供参考
1,形参如果是数组、自定义变量、对象变量,则只能用传址方式
2,形参前用了Byval,或者对应参数是常数、表达式,都是传值方式
3,形参前为Byref,或者没有关键词,都是传址方式
4,实参为变量,且变量放在括号内,如“(a)”,则为传值。这种情况不多见

“传址”还是“传值”,该怎么选择呢?
1,如果希望通过过程调用,并修改对应实参的数值,用传址
例如:要实现两个变量值的交换,宜用传址
例如:要计算三个数的累加和额函数过程,在定义形参时,宜用传值。因为不希望在函数调用后,这三个参数值有什么改变
2,传址方式的速度快,但增加了过程的相互牵连;也不利于程序调试。而传值则相反
在实际中,可以先用传值方式,等调试后,再改为传址方式
3,用传址方式,要求实参与形参的数据类型完全一致
4,形参表中允许出现可选参数,用关键字optional
所有可选参数必须位于形参表的最后,每个可选参数前必须有关键字 optional
主调过程调用时,如果没有提供可选参数,该参数作为具有empty值的变量来赋值

TA的精华主题

TA的得分主题

发表于 2015-6-23 09:55 | 显示全部楼层
对于菜鸟 最好是什么都不写 默认的 就行了不然傻傻分不清的结果是 混乱

TA的精华主题

TA的得分主题

发表于 2015-6-23 10:16 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
呵呵,要了解计算机内部机制就不难理解了!!!

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-6-23 10:26 | 显示全部楼层
百度不到去谷歌 发表于 2015-6-23 09:55
对于菜鸟 最好是什么都不写 默认的 就行了不然傻傻分不清的结果是 混乱

主要是理解 传址和传值
这两种方式,尤其是省略byref的方式,写代码时几乎是躲不开的
而在使用子过程(sub),函数(function)的场合,常常稀里糊涂利用“双向传递”,把传入的参数和传出的参数统统写到参数表中了。事实上多数情况也没有出错
但是,如果遇到一楼的情况就出错了。

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-6-26 08:45 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 yiyiyicz 于 2015-6-26 08:49 编辑

对于初学者,最简单的方式就是采用省略方式,即传址
形参表与实参表中的变量,一一对应,不要出现一楼的情况。也就是不要玩什么花样,基本不会出问题。即便如6楼运用“双向传递”也很少出问题。6楼所提到的方法,在实际编程中,比较常用
上述规则,在处理比较复杂的程序中,会用到的

TA的精华主题

TA的得分主题

发表于 2019-6-25 14:38 | 显示全部楼层
找尽网上都不找不到的经典教程,一个简单的实例把按值传递(微软官方定义,习惯称为值传送),和按引用传递(习惯称为地址传送)讲得明明白白!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-4-24 07:56 , Processed in 0.044425 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表