批处理中for循环的自增自减问题

批处理(Batch),也称为批处理脚本,文件的扩展名为.bat 。批处理就是对某对象进行批量的处理,通常被认为是一种简化的脚本语言,它应用于DOS和Windows系统中。批处理有着非常强大的处理功能。

下面是我在使用批处理是遇到的一个坑,关于for循环中自增自减问题:
目的:大概简单说就是一个循环中变量递增,并新开一个进程将该值作为参数传入
代码:

@echo off
set /a n=5
for /l %%i in (1 1 10) do (
    set /a n+=1
    start "" ***.exe %n%
)
echo %n%

结果:新开的进程传入的参数都是5,打印出来的值也都是5
这里写图片描述

【原因】:命令解释器是扩展环境变量的行为大致如下:首先读取命令行的一条完整语句,在进行一些先期的预处理之后,命令被解释执行之前,会对其中用百分号闭合的字符串,进行匹配,如果在环境空间中找到了与字符串相匹配的环境变量则用其值替换掉原字符串及百分号本身,如果未得到匹配,则用一个空串替换,这个过程就是环境变量的“扩展”,它仍然属于命令行的预处理范畴。【来自网上】

经过上面的解释,我们可以发现,CMD在读取for语句时,它会将整个for循环(包括后面’()’中的内容)当成一个完整的语句。同事它会在环境变量中查找需要的字符串。在上面的例子中,他会在查找名为n的环境变量,并用环境变量的值将%n%替换掉,此时n就变成了一个常量,所以自增自减在for循环中它的值一直都是5。

so,在循环中,变量自增没有其作用,但是,再循环外打印n的值就会发现他是正常的:
这里写图片描述
咦,为什么在出for循环后,或者别的方法还可以得到预期的值呢?
【原因】:那是因为虽然for循环中n当成了一个常量,但是自增自减时改变了名为n的环境变量。而出for循环后,‘echo %n%’已经成为下一条语句了,解释器会继续查找名为n的环境变量,而此时环境变量n的值寂静变为了15.

再看下免得例子:加入setlocal enabledelayedexpansion语句,并用!!把变量n括起来:

@echo off
set /a n=5
setlocal enabledelayedexpansion
for /l %%i in (1,1,10) do (
    set /a n+=1
    start "" ***.exe %n%
    echo !n!
)
pause

这里写图片描述
发现不只是出循环才能打印出更改后的值,原来每一次更改都可以显示,这不是和第一种情况解释冲突了吗?

【原因】:其中的奥秘就是启动了变量延迟。变量延迟的启动语句是setlocal enabledelayedexpansion ,但是要注意的是,必须将变量用!!括起来才会起作用,这样解释器才会认定这个变量是需要延迟的。整个过程为:首先“setlocal enabledelayedexpansion”开启变量延迟,“set /a n+=1”由于启动了变量延迟,所以批处理能够感知到动态变化,即不是先给该行变量赋值,而是在运行过程中给变量赋值,因此打印出的n值是实时变化的。

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值