本帖最后由 Nsqs 于 2017-3-30 22:14 编辑
变量延迟其实很好理解.
首先分清一个概念.什么是全局变量什么是局部变量
全局变量
是指整个程序可见,比如- @echo off
- call:1
- echo %[变量]%
- pause
- exit
- :1
- set "[变量]=可以看见我"
- goto :eof
复制代码 局部变量
是指仅仅局部区域可见,可参见如下效果- @echo off
- (
- call:1
- echo %[变量]%
- )
- pause
- exit
- :1
- set "[变量]=可以看见我"
- goto :eof
复制代码 或者也可以这样- @echo off
- set [变量]=可以看见我
- echo %[变量]%
- pause
复制代码 或这样,变为无法输出的变量- @echo off
- (
- set [变量]=可以看见我
- echo %[变量]%
- )
- pause
复制代码 然后再来谈谈为什么括号被括起来后就无法输出变量的值了呢,那就是作用域的问题,变量被限制在括号内变为不可见
如果想可见必须使用call 即如下写法- @echo off
- (
- set [变量]=可以看见我
- call echo %%[变量]%%
- )
- pause
复制代码 也可以开启变量延迟- @echo off
- setlocal enabledelayedexpansion
- (
- set [变量]=可以看见我
- echo ![变量]!
- )
- pause
复制代码 当然还有复杂一点的变量嵌套写法,比如- @echo off
- set [变量][0]=b
- set [变量][1]=a
- set [变量][2]=t
- for /l %%1 in (0 1 2)do (
- call set /p=%%[变量][%%1]%%<nul
- )
- pause
复制代码 以及- @echo off
- set "[变量][0]=b"
- set "[变量][1]=a"
- set "[变量][2]=t"
- for /l %%1 in (0 1 2)do (
- set /p=%%[变量][%%1]%%<nul
- )
- pause
复制代码 后者显示不出bat3个字,这是为什么呢?
答:因为如果你在变量里嵌套变量,内层的变量就被当作局部处理,而必须开启变量延迟或者调用call 来让外层变量看到内层变量才行
还有一些其他的例子比如- @echo off
- set "[变量]=这是一个例子"
- for /f "tokens=1 delims=:" %%1 in ('^(echo %[变量]%^&echo;^)^|findstr /o ".*"')do set /a n=%%1-3
- for /l %%1 in (0 1 %n%)do (
- call set /p=%%[变量]:~%%1,1%%<nul
- )
- echo;
- pause
复制代码 或者- @echo off
- set "[变量]=这是一个例子"
- for /f "tokens=1 delims=:" %%1 in ('^(echo %[变量]%^&echo;^)^|findstr /o ".*"')do set /a n=%%1-3
- for /l %%1 in (0 1 %n%)do (
- set /p=%[变量]:~%%1,1%<nul
- )
- echo;
- pause
复制代码 最后一例- @echo off
- for /l %%1 in (9 -1 1)do (
- call set n=%%n%%%%1
- )
- call:1 %n%
- pause
- exit
- :1
- for /l %%i in (1 1 9)do (
- call set/p=%%%%i <nul
- )
- goto :eof
复制代码 不用call显然也无法输出- @echo off
- for /l %%1 in (9 -1 1)do (
- call set n=%%n%%%%1
- )
- call:1 %n%
- pause
- exit
- :1
- for /l %%i in (1 1 9)do (
- set/p=%%%i <nul
- )
- goto :eof
复制代码 疑问:
1.为什么变量在for内赋值后无法得到其值或计算错误
答:因为变量在for内是属于局部变量
2.为什么变量在if内无法进行布尔运算
答:因为if的条件判断必须开启变量延迟,无法使用call if XXX
3.为什么一定要使用!(开启变量延迟)呢?
答:一般来讲尽量不开.一个是在写的过程中会麻烦一点,另一个就是在很多时候变量延迟带来的麻烦地方也不少
就不一一举例了.比如输出一段字符串时必须用^转义(即^!)
4.有些时候使用!xx:~!yy!,1!无效怎么办?
答:这种写法是错误的,只有两种写法,根据实际情况来决定,一个是call echo !xx:~%%yy%%,1! ,另一个是
call echo %%xx:~!yy!,1%%.具体一般用前者还是后者,是看情况的.作用不同的时候前后其中一个肯定用不了,
不过多用于后者的情况比较多.然后就是这种混合写法前提是必须开启变量延迟.
5.for循环中的%%X变量和call %%X%%容易搞混,或代码写多了万一分不清怎么办?
答:自己写的程序想到哪写到哪,应该不会犯这种错误,要分清他们哪个是循环中的变量哪个是普通的变量很简单,
for中的变量是%%A-Z1-9 一个字符在后,并且只能用一个字表示.分清这点就可以使用call了
最后要说的就是开启变量延迟或者用call的效果是一样的,只是call的使用上比较强大.既能call:标签也能call程序、也能调用变量.
如果你耐心看完和测试以上所有的代码并加以分析和理解,你会发现其实很简单.理解上面所有代码你就可以处理很多问题了 |