标题: [原创] 批处理中set /a 极大的误区 [打印本页]
作者: defanive 时间: 2009-1-17 15:30 标题: 批处理中set /a 极大的误区
关于 set /a 中极大的误区,几乎所有的批处理教材中都有这个错误,误导了至少80%的人!
这句:set /a a+=1
一切教学资料上的解释都是:与
set /a a=%a%+1
相等同!
那么我们做一个有趣的实验:- @echo off
- set a=0
- for /l %%b in (1,1,5) do set /a a+=1
- echo a=%a%
- pause
复制代码
得到的输出是:
a=5
请按任意键继续. . .
那么根据教材所说的,等同于 set /a a=%a%+1 ,我们测试一下效果:- @echo off
- set a=0
- for /l %%b in (1,1,5) do set /a a=%a%+1
- echo a=%a%
- pause
复制代码
得到的输出是:
a=1
请按任意键继续. . .
教材和资料都错了!
正确的解释应是:set /a a+=1 与 set /a a=a+1 对等!
多了两个%括住就造成的极大的错误!
正确对等的代码是:
@echo off
set a=0
for /l %%b in (1,1,5) do set /a a=a+1
echo a=%a%
pause
输出:
a=5
请按任意键继续. . .
当然,无聊的话下面这样写也是对等的,当然及不简便:- @echo off
- setlocal enabledelayedexpansion
- set a=0
- for /l %%b in (1,1,5) do set /a a=!a!+1
- echo a=%a%
- pause
复制代码
开启变量延迟,用!括住也是正确的
那么,请大家看完这篇东西之后,记住不要再犯同样的错误,同样不要再去误导他人:
set /a a+=1
不等于
set /a a=%a%+1
应等于
set /a a=a+1
作者: tireless 时间: 2009-1-17 16:46
是预处理的关系吧,与 set 无关。
set a=0
for /l %%b in (1,1,5) do set /a a=%a%+1
当读取以上整个 for 语句后,执行语句前进行了预处理,最后实际执行的是:
for /l %%b in (1,1,5) do set /a a=0+1
[ 本帖最后由 tireless 于 2009-1-17 18:35 编辑 ]
作者: defanive 时间: 2009-1-17 18:02
通常的讲,set /a a+=1正确的应该是set /a a=a+1而不是set /a a=%a%+1
实际上for这五次set /a a=%a%+1的变量设置都被延迟了
但是set /a a=a+1是set /a的一个特性,设置的变量会立即生效
所以set /a a+=1就结果来看,是立即生效的,对应的应该是set /a a=a+1
的确不关set的事,关教材资料的事
作者: pusofalse 时间: 2009-1-17 18:15
特性如此~- If you use any of the logical or modulus operators, you will need to
- enclose the expression string in quotes. Any non-numeric strings in the
- expression are treated as environment variable names whose values are
- converted to numbers before using them. If an environment variable name
- is specified but is not defined in the current environment, then a value
- of zero is used. This allows you to do arithmetic with environment
- variable values without having to type all those % signs to get their
- values.
复制代码
This allows you to do arithmetic with environment
variable values without having to type all those % signs to get their
values.
set /a a=%a%+1实际执行的是set /a a=+1而不是set /a a=0+1
set /a a=a+1 才是set /a a=0+1,但在for中它是会实时改变的。
作者: BBCC 时间: 2009-1-17 21:12
所以说,微软在这方面做得很乱,两个标准……
作者: sjzong 时间: 2009-4-14 15:42
哦!谢谢楼主,以后要注意了!
作者: 鳌头七队 时间: 2011-6-1 19:32
是批处理的变量延迟搞的鬼
作者: Demon 时间: 2011-6-1 19:49
那些垃圾教程只会误人子弟罢了
作者: qzwqzw 时间: 2011-6-1 21:25
说实话,
没有看到哪里的教材是这样写的
楼主提及“几乎所有的批处理教材”
不知是否能够例举一二?
作者: Batcher 时间: 2011-6-1 23:31
这个帖子也许是楼主刚接触批处理的时候写的,大家淡定了。
作者: applba 时间: 2011-6-2 04:52
set命令能够自行识别变量名,并完成变量值的替换。
还有一个用法类似,if defined varname,也不需要%。
作者: szylmzs 时间: 2011-6-2 09:47
应该是变量延迟的问题
作者: cjiabing 时间: 2011-6-3 21:46
哈哈,我比较怕数学,没有上过当,不过现在经常用到set /a a+=1,其它两个用得少。
写教材一定要自己亲自测试过代码才可以引用,否则害人不浅!~
作者: andy七少 时间: 2011-6-9 12:40
for中的%a%只会应用上一个语句set设置的环境变量
还是变量延迟高的鬼嘛!
作者: guaiwu 时间: 2011-10-4 16:12
有心提醒了。 心意领会了
作者: Fantasys 时间: 2011-10-12 17:59
我觉得官方解释不能说错,只是在批处理有些特别的地方罢了。开启变量延迟就可以了,说明它解释还是对的。
作者: 网上邻居 时间: 2016-3-17 14:41
预处理机制而已。
作者: 小程936 时间: 2016-6-17 09:38
set /a x=a,a=b,b=x
可以交换a和b的位置,你怎么看?
作者: ai20110304 时间: 2016-10-20 23:33
谢谢 分享
作者: tiger999 时间: 2017-1-27 15:07
QAQ LZ不要误导别人啊,吓得差点误解了我习惯了3年的知识
这是因为变量延迟的问题,这和所谓的%%没有关系
你只需要加一个setlocal enabledelayedexpansion,把%换成!就好了,QAQ
作者: ShenMian 时间: 2018-2-18 00:31
这是延迟变量的问题,而不是什么教程乱讲。若考虑延迟变量应该写为set /a a+=1等价于set /a a=!a!+1,如果没有开启本地自动化操作则是错误的语句。所以set /a a=%a%+=1并没有错误。
作者: ai20110304 时间: 2018-8-29 23:29
回复 11# applba
大侠说到点子上了。细心点发现
作者: ai20110304 时间: 2018-8-29 23:31
回复 1# defanive
这个复合运算符隐含延迟变量的功能。就像java中复合运算符隐式一个强制类型转换
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |