找回密码
 加入
搜索
查看: 3941|回复: 14

[AU3基础] 关于数组下标调用函数的奇怪问题,百思不得其解...[已解决]

[复制链接]
发表于 2020-10-10 14:48:27 | 显示全部楼层 |阅读模式
本帖最后由 gapkiller 于 2020-10-14 15:08 编辑

为何Test()被调用了200次?
#include <Array.au3>
Global $aTest[3]=[0,0,0]
Global $iCall = 0
For $i=1 To 100
        $aTest[Test()] += 1
Next

_ArrayDisplay($aTest, $iCall)

Func Test()
        $iCall += 1
        Return Random(0,2,1)
EndFunc
发表于 2020-10-13 12:31:32 | 显示全部楼层
$aTest[Test()]  =  $aTest[Test()] + 1执行时,先计算右边的值(Test()会运行1 次),再将值赋给左边数组元素,但左边的数组元素是哪个?还要再执行 一次Test()才能确定,故每一次计数Test()会运行2次。

评分

参与人数 1金钱 +10 收起 理由
gapkiller + 10 谢谢回复

查看全部评分

发表于 2020-10-10 16:12:02 | 显示全部楼层
$aTest[Test()] += 1就是  $aTest[Test()]  =  $aTest[Test()] + 1
是执行了两次噻。

评分

参与人数 1金钱 +10 收起 理由
gapkiller + 10 谢谢回复

查看全部评分

 楼主| 发表于 2020-10-10 15:25:28 | 显示全部楼层
但如果改为如下代码,就没问题了
#include <Array.au3>
Global $aTest[3]=[0,0,0]
Global $iCall = 0
For $i=1 To 100
        $iTemp = Test()
        $aTest[$iTemp] += 1
Next

_ArrayDisplay($aTest, $iCall)

Func Test()
        $iCall += 1
        Return Random(0,2,1)
EndFunc
 楼主| 发表于 2020-10-10 17:01:07 | 显示全部楼层
本帖最后由 gapkiller 于 2020-10-10 17:03 编辑
zch11230 发表于 2020-10-10 16:12
$aTest[Test()] += 1就是  $aTest[Test()]  =  $aTest[Test()] + 1
是执行了两次噻。
这样吗? 感觉还是很奇怪...照理应该先执行Test(),再代入+=1
发表于 2020-10-10 18:55:15 | 显示全部楼层
学习了,3楼正解,。。。。。。。。。

加了个调试,控制台。。。可以看到的确是  执行了两次
#include <Array.au3>
Global $aTest[3]=[0,0,0]

;~ _ArrayDisplay($aTest,'Debug~~~')

Global $iCall = 0
For $i=1 To 100
        ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $i = ' & $i & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
        $aTest[Test()] += 1
Next

_ArrayDisplay($aTest, $iCall)

Func Test()
        $iCall += 1
                ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $iCall = ' & $iCall & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
        Return Random(0,2,1)
;~         Return $iCall
EndFunc

评分

参与人数 1金钱 +10 收起 理由
gapkiller + 10 是执行了两次,但不是3楼的答案.

查看全部评分

 楼主| 发表于 2020-10-13 13:08:16 | 显示全部楼层
shqf 发表于 2020-10-13 12:31
$aTest[Test()]  =  $aTest[Test()] + 1执行时,先计算右边的值(Test()会运行1 次),再将值赋给左边数组 ...

如果是这样的话, $aTest三个数之和就不会等于100, 可结果确实是100
 楼主| 发表于 2020-10-13 13:16:22 | 显示全部楼层
gapkiller 发表于 2020-10-13 13:08
如果是这样的话, $aTest三个数之和就不会等于100, 可结果确实是100

可怕的是, 我把
$aTest[Test()] += 1
改为
$aTest[Test()] = $aTest[Test()] + 1
后, $iCall变成300了....

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2020-10-13 13:55:08 | 显示全部楼层
数组赋值,下标嵌套函数就会被调用两次,以后可得注意不能这样用了,效率降低一半
Global $aTest[1]
$aTest[Test()] = 0

Func Test()
        MsgBox(0, 0, 0)
EndFunc   ;==>Test
 楼主| 发表于 2020-10-13 15:40:23 | 显示全部楼层
afan 发表于 2020-10-13 13:55
数组赋值,下标嵌套函数就会被调用两次,以后可得注意不能这样用了,效率降低一半

感觉是个bug, 有些奇怪.
发表于 2020-10-13 16:38:46 | 显示全部楼层
gapkiller 发表于 2020-10-13 15:40
感觉是个bug, 有些奇怪.

同感~ 不过我一般是不会这样用,最多内嵌 UBound()
 楼主| 发表于 2020-10-14 12:57:23 | 显示全部楼层
afan 发表于 2020-10-13 16:38
同感~ 不过我一般是不会这样用,最多内嵌 UBound()

搞不好UBound()也被执行了两次, 我做了个实验, 先把Ubound($aArr)赋值给一个临时变量, 再带入下标计算, 效率更高....
Local $aArr[100]
Local $iTemp
$ti = TimerInit()

For $i = 1 To 1000
        $iTemp = UBound($aArr)-1
        $aArr[$iTemp] = 100
;~         $aArr[UBound($aArr)-1] = 100
Next
$td = TimerDiff($ti)
MsgBox(0,0,$td)
发表于 2020-10-14 13:11:37 | 显示全部楼层
gapkiller 发表于 2020-10-14 12:57
搞不好UBound()也被执行了两次, 我做了个实验, 先把Ubound($aArr)赋值给一个临时变量, 再带入下标计算,  ...

肯定是一样执行两次,只是因为这个几乎忽略不计而已。如果在循环体中肯定不会这样做
 楼主| 发表于 2020-10-14 13:55:35 | 显示全部楼层
afan 发表于 2020-10-14 13:11
肯定是一样执行两次,只是因为这个几乎忽略不计而已。如果在循环体中肯定不会这样做

怎么把标签改为与解决的??找不到这个标签了...
发表于 2020-10-14 14:52:26 | 显示全部楼层
gapkiller 发表于 2020-10-14 13:55
怎么把标签改为与解决的??找不到这个标签了...

没有这个分类,都是加几个字就行了
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-11-1 08:11 , Processed in 0.079457 second(s), 23 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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