找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 80159|回复: 23

[原创] 批处理中set /a 极大的误区

[复制链接]
发表于 2009-1-17 15:30:38 | 显示全部楼层 |阅读模式
关于 set /a 中极大的误区,几乎所有的批处理教材中都有这个错误,误导了至少80%的人!

这句:set /a a+=1
一切教学资料上的解释都是:与
set /a a=%a%+1
相等同!

那么我们做一个有趣的实验:
  1. @echo off
  2. set a=0
  3. for /l %%b in (1,1,5) do set /a a+=1
  4. echo a=%a%
  5. pause
复制代码
得到的输出是:
a=5
请按任意键继续. . .

那么根据教材所说的,等同于 set /a a=%a%+1 ,我们测试一下效果:
  1. @echo off
  2. set a=0
  3. for /l %%b in (1,1,5) do set /a a=%a%+1
  4. echo a=%a%
  5. 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
请按任意键继续. . .

当然,无聊的话下面这样写也是对等的,当然及不简便:
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set a=0
  4. for /l %%b in (1,1,5) do set /a a=!a!+1
  5. echo a=%a%
  6. pause
复制代码
开启变量延迟,用!括住也是正确的



那么,请大家看完这篇东西之后,记住不要再犯同样的错误,同样不要再去误导他人:
set /a a+=1
不等于
set /a a=%a%+1
应等于
set /a a=a+1

评分

参与人数 2PB +5 技术 +1 收起 理由
Hello123World + 1 乐于助人
Batcher + 5 感谢分享

查看全部评分

发表于 2009-1-17 16:46:04 | 显示全部楼层
预处理的关系吧,与 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 编辑 ]

评分

参与人数 1技术 +1 收起 理由
jellyhk + 1 正解

查看全部评分

 楼主| 发表于 2009-1-17 18:02:34 | 显示全部楼层
通常的讲,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的事,关教材资料的事
发表于 2009-1-17 18:15:17 | 显示全部楼层
特性如此~
  1. If you use any of the logical or modulus operators, you will need to
  2. enclose the expression string in quotes.  Any non-numeric strings in the
  3. expression are treated as environment variable names whose values are
  4. converted to numbers before using them.  If an environment variable name
  5. is specified but is not defined in the current environment, then a value
  6. of zero is used.  This allows you to do arithmetic with environment
  7. variable values without having to type all those % signs to get their
  8. 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中它是会实时改变的。
发表于 2009-1-17 21:12:09 | 显示全部楼层
所以说,微软在这方面做得很乱,两个标准……
发表于 2009-4-14 15:42:11 | 显示全部楼层
哦!谢谢楼主,以后要注意了!
发表于 2011-6-1 19:32:43 | 显示全部楼层
是批处理的变量延迟搞的鬼
发表于 2011-6-1 19:49:32 | 显示全部楼层
那些垃圾教程只会误人子弟罢了
发表于 2011-6-1 21:25:10 | 显示全部楼层
说实话,
没有看到哪里的教材是这样写的
楼主提及“几乎所有的批处理教材”
不知是否能够例举一二?
发表于 2011-6-1 23:31:31 | 显示全部楼层
这个帖子也许是楼主刚接触批处理的时候写的,大家淡定了。
发表于 2011-6-2 04:52:19 | 显示全部楼层
set命令能够自行识别变量名,并完成变量值的替换。
还有一个用法类似,if defined varname,也不需要%。
发表于 2011-6-2 09:47:00 | 显示全部楼层
应该是变量延迟的问题
发表于 2011-6-3 21:46:17 | 显示全部楼层
哈哈,我比较怕数学,没有上过当,不过现在经常用到set /a a+=1,其它两个用得少。
写教材一定要自己亲自测试过代码才可以引用,否则害人不浅!~
发表于 2011-6-9 12:40:42 | 显示全部楼层
for中的%a%只会应用上一个语句set设置的环境变量
还是变量延迟高的鬼嘛!
发表于 2011-10-4 16:12:02 | 显示全部楼层
有心提醒了。   心意领会了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 06:27 , Processed in 0.030518 second(s), 13 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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