网易首页 > 网易号 > 正文 申请入驻

VB/VBA之Boolean的坑,防不胜防,治标还得治本!

0
分享至

前言

各位熟悉VB/VBA的童鞋们,对Boolean肯定是再熟悉不过了,因为它是匹配计算机二进制世界的逻辑门,任何算法逻辑的推演都离不开Boolean的支持。但是,对于VB/VBA中的Boolean坑点,大家都有踩到过吗?

Boolean导致的Bug,在对Boolean缺乏深入的认识前,是极难发现的。笔者就曾吃过不少亏,本文就将这些吃亏的经历,以及如何从根本上避免,给大家做个分享。期待能对大家有所帮助,少走弯路。

一、一起来踩坑

Boolean类型,看上去很简单,要讲起来似乎也凑不出个123来,渐渐地便理所当然起来。比如在If语句中,要么为了简洁省事,要么为了效率,就有如下变化:“if Var<>0 then”逐步写成 “if Var then”,这的确可以提高效率。于是“if not (Var<>0) then”是不是顺手写成了“if not Var then”?

在《VB的整数,你真的了解?》中,已经提醒大家要谨慎了。若不信,可以将Var随便赋值一个非0值,来测试测试吧。怎么样?原以为可以提高效率,没想到掉到坑里了吧。

再来看VB/VBA中使用API时的坑吧。在《VB变量的重构,横看成岭侧成峰》中给大家讲到,VB/VBA可将1、2、4字节类型传递给Long类型。而API的参数几乎都是Long类型的,因为指针可用该类型表示,1、2、4字节的数值类型更可以使用该类型表示(具体可参考《VB中Byte、Boolean和Integer与Long的开销及性能相同吗?》)。这使得在VB/VBA中声明API函数时,有极大的灵活性,对参数类型可以自作主张地进行本地化改造。比如,可以将字符串缓冲区指针,声明为String类型,从而避免使用VB中不方便的指针。

很多API函数会使用Bool类型,通过非0整数表示True,用0表示False。那在VB/VBA中声明使用这些API函数时,为了简单明了,自然可以声明为Boolean类型,相信大家经常这么干。通常情况下,不会遇到什么麻烦。但是,在极少数情况下,这里面的坑就会让人很难受。

比如判断指定进程是32位还是64位,通常会使用IsWow64Process函数。其第二个参数(Wow64Process),通常当进程运行在64位系统的Wow64环境中时,会返回True。若在VB/VBA中将该参数声明为Boolean类型,而恰巧又对于该参数的返回值,使用了Not 运算符来表示与64位的匹配性。如"Not Wow64Process",期望Wow64Process=True时表示非64位,Wow64Process=False时表示64位。

如果读者,在任务管理器中选择标识为32位的进程,跟着去做个验证,很快就会发现结果并不正确。利用VB/VBA强大的逐句调试功能,很快就会发现,"Not Wow64Process"中,Wow64Process明明为True,但这个"Not True"的结果仍然为True。这让人百思不得其解,甚至怀疑Not运算符是不是有什么讲究,或者VB/VBA本来就很那个才有如此漏洞。

如果,不深入了解VB/VBA中的Boolean,即便找到了Bug所在,也只会怀疑人生,甚至对VB/VBA失去好感。接下来,让我们看看,究竟是怎么一回事呢?

二、重新认识VB/VBA中的Boolean

一提到Boolean,大家自然会想到True和False。没错,通常我们将Boolean与True/False进行等同,并混淆使用,这也是错误发生的根源所在。True和False是VB/VBA中定义的两个常量,其中True为-1(0xFFFF),False为0(0x0000)。如有怀疑,可以使用Hex函数进行验证。在以前的《VB的整数,你真的了解?》中也对此进行了分析,False的定义几乎是通用的,唯独要谨慎True的定义。

根据VB/VBA对True的定义,Not True的确为False。或许当年的设计者们,就是为了获得这种理解上的统一吧。但是,Boolean类型却是和系统定义一致的,也即非0为True,0为False。为了更清楚地说明问题所在,可以定义1个Boolean类型的变量uBool,uBool=1之后,发现uBool的结果为True,但Not uBool却仍然为True,显然与前面提到的Bug如出一辙。

我们知道VB/VBA中的Boolean类型,其实是个2字节有符号整数(详见《VB的整数,你真的了解?》)。前述uBool尽管结果为True,但其内存里装的却是1,Not uBool其实就是Not 1,这结果怎么可能为0呢!同样,对于前面提到的Bug,若用Hex函数查看Wow64Process参数的返回值,发现这个True,其实就是1。

这样一来,VB中的True就容易产生“二义性”,这就是关于Boolean有关坑爹的源头。总之一句话,Boolean类型变量的True并不能等同于True常量。

三、如何避免踩到Boolean的坑

既然知道VB/VBA中的True具有“二义性”,那就得弄清里面的原因,否则又该怪罪VB/VBA了。

对于Boolean类型的变量而言,VB/VBA的封装机制,让其将非0都解释为True,但这个True是个解释用的临时值,它并不会更改变量内存值为True这个常量值。当我们使用监视功能时,显示的就是这个临时值。这个临时值,是不会参与针对变量内存的相关运算的。

至此,其实已经很清楚了,无论是常量还是变量,都要从内存结构上去理解。尤其是VB/VBA为了提高易用性,在封装层面进行了大量的拟人化,这很容易让使用者弄不清里面的原委。其实,这个“二义性”正是常量和变量的混淆导致的,如果理解清楚了,也就没有所谓的“二义性”了。

如此,再回头来看,就清楚为什么“if uBool then ”与“if uBool<>0 then”等效且更高效了。uBool和uBool<>0均为条件表达式,条件表达式是需要计算出结果的,不存在临时结果一说。前者的计算结果就是解释值True,而后者不仅需要解释uBool,而且解释值还要参与比较运算。那“if not uBool then”为什么会存在问题呢?因为Not是按位取反,会涉及uBool变量的内存,使用的自然是uBool的内存值,而非解释值呀。

怎么样,看到这里有没有眼前一亮?欢迎关注BtOfficer,阅读更多有意思的知识点。各位读者在使用VB/VBA(其他语言,需等承诺的相关工具放出后,再分享)过程中,若有任何困惑可留言哦,将视情况进行专题解答分享哦。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
全世界都愤怒了,但美国却说:未过红线

全世界都愤怒了,但美国却说:未过红线

观察者网
2024-05-29 08:32:07
情侣因长得太像,为满足好奇心去做亲缘鉴定,当事人:结果出来了

情侣因长得太像,为满足好奇心去做亲缘鉴定,当事人:结果出来了

风起云间
2024-05-28 21:48:26
官方确认已不幸离世,年仅31岁.

官方确认已不幸离世,年仅31岁.

华人星光
2024-05-28 15:23:08
三上悠亚半素颜现身街头:真实样貌曝光网友惊呆

三上悠亚半素颜现身街头:真实样貌曝光网友惊呆

葫芦哥爱吐槽
2024-05-29 05:37:54
白岩松:夜查电动车是为了防火!网友:夜查贪官老百姓会更支持!

白岩松:夜查电动车是为了防火!网友:夜查贪官老百姓会更支持!

韩观社会
2024-05-29 05:13:03
俄罗斯宣布进入紧急状态,巨亏之下俄天然气公司生产洗衣机自救

俄罗斯宣布进入紧急状态,巨亏之下俄天然气公司生产洗衣机自救

史政先锋
2024-05-28 21:00:36
震惊!14岁镇中女孩与一起“聚众淫乱案”,这次是谁的责任?

震惊!14岁镇中女孩与一起“聚众淫乱案”,这次是谁的责任?

教育人看世界
2024-05-28 18:04:43
李湘携女儿回北京,深山内拜访艺术大师,合影曝光王诗龄很谦卑

李湘携女儿回北京,深山内拜访艺术大师,合影曝光王诗龄很谦卑

缘浅娱深
2024-05-28 17:07:22
多国政客谈论“开战”可能,俄方警告或致局势失控,欧洲对俄乌冲突分歧加剧

多国政客谈论“开战”可能,俄方警告或致局势失控,欧洲对俄乌冲突分歧加剧

环球网资讯
2024-05-29 06:36:25
国家安全部:1人向从事间谍活动嫌犯通风报信被行拘

国家安全部:1人向从事间谍活动嫌犯通风报信被行拘

新京报
2024-05-29 08:37:06
原来鸽子这么可怕!网友科普后背发凉,难怪说鸽子是天上的老鼠

原来鸽子这么可怕!网友科普后背发凉,难怪说鸽子是天上的老鼠

大宗看萌宠
2024-05-28 12:36:10
刘强东“变脸”再次证明:在民营企业没有前途,考公才是人间正道

刘强东“变脸”再次证明:在民营企业没有前途,考公才是人间正道

叮当当科技
2024-05-29 05:54:10
刘强东彻底愤怒:有年薪百万高管当天清退,上万代打卡员工被清查

刘强东彻底愤怒:有年薪百万高管当天清退,上万代打卡员工被清查

影像温度
2024-05-28 16:33:56
对普通人喊打喊杀,对处级干部致人死亡却视而不见

对普通人喊打喊杀,对处级干部致人死亡却视而不见

顾礼先生
2024-05-28 16:08:19
3-2!中国女排爆冷,替补逆转主力阵容,朱婷独得26分

3-2!中国女排爆冷,替补逆转主力阵容,朱婷独得26分

邮轮摄影师阿嗵
2024-05-29 02:37:43
库里第2个儿子出生,尊重妻子用中国姓氏取名!球迷:赶紧归化

库里第2个儿子出生,尊重妻子用中国姓氏取名!球迷:赶紧归化

十点街球体育
2024-05-28 17:17:23
孙春兰,访问意大利

孙春兰,访问意大利

意讯
2024-05-28 20:35:00
舒淇和冯德伦的瓜也太大了,朋友圈都炸锅了!

舒淇和冯德伦的瓜也太大了,朋友圈都炸锅了!

听风听你
2024-05-29 00:01:13
台湾上空发生激烈交锋,中美军机交手,专家发现不对:大陆咋来的

台湾上空发生激烈交锋,中美军机交手,专家发现不对:大陆咋来的

星辰故事屋
2024-05-27 22:00:17
小托马斯自曝差点丧命!年轻人用AK47对准他 被认出后才逃过一劫

小托马斯自曝差点丧命!年轻人用AK47对准他 被认出后才逃过一劫

罗说NBA
2024-05-29 05:41:33
2024-05-29 10:06:44
BtOfficer
BtOfficer
安全,办公,工具,情报,文字
88文章数 1016关注度
往期回顾 全部

科技要闻

比亚迪重磅发布:最高续航2500KM

头条要闻

菲方抗议中国实施休渔期 宣称此举令南海局势紧张升级

头条要闻

菲方抗议中国实施休渔期 宣称此举令南海局势紧张升级

体育要闻

阿根廷一代神锋,击碎了沙特的金元足球梦

娱乐要闻

昆凌晒三胎正面照,2岁妹妹超像周杰伦

财经要闻

东方通收购藏雷 花6亿买来"业绩变脸"

汽车要闻

三联屏/纯电续航318km 岚图FREE 318官图发布

态度原创

房产
亲子
本地
时尚
公开课

房产要闻

有点猛!最新房价:海南每㎡跌了2000多!

亲子要闻

妈妈带小女孩在公园玩站在长椅上就像个洋娃娃网友:又是骟生女儿系列

本地新闻

食味印象|歙县限定!枇杷味儿的清甜初夏

50岁女人的搭配技巧解析,配饰精致大方,穿浅色更年轻有活力

公开课

近视只是视力差?小心并发症

无障碍浏览 进入关怀版