无忧启动论坛

标题: 怪事:写了三次pause竟然停了4次(8楼有更大的问题) [打印本页]

作者: sunsea    时间: 2012-2-19 08:57
标题: 怪事:写了三次pause竟然停了4次(8楼有更大的问题)
  1. @echo off
  2. pause
  3. call :r 0015.3
  4. pause
  5. :r
  6. set hf=%1
  7. ::set hf==A%$d=$!=%t:*=%*=!!%!%=%hf:*^=%=?%#%|ECHO YY
  8. echo %hf%
  9. pause
复制代码
里面只有三个pause,却停了四次:

接下来加一句echo:
  1. @echo off
  2. pause
  3. call :r 0015.3
  4. pause
  5. :r
  6. set hf=%1
  7. ::set hf==%t:*=%*=!!A%$d=$!=%!%=%hf:*^=%=?%#%|ECHO YY
  8. echo %hf%
  9. pause
复制代码
结果更奇怪:


为什么?

[ 本帖最后由 2011czmxbb52 于 2012-2-19 13:40 编辑 ]
作者: sratlf    时间: 2012-2-19 10:36
标题: 回复 #1 2011czmxbb52 的帖子
@echo off
pause
call :r 0015.3
pause
:r
set hf=%1
::set hf==A%$d=$!=%t:*=%*=!!%!%=%hf:*^=%=?%#%|ECHO YY
echo %hf%
pause



执行流程如下

pause
::跳至r标签处理
set hf=%1
echo %hf%
pause
::r标签处理结束
::call结束 返回原处继续向下执行
pause
::准确来说在上面的pause后应该接一个exit  否则的话就会继续向下执行  这也是第四个pause出现的原因
set hf=%1
echo %hf%
pause

作者: jh1688    时间: 2012-2-19 11:20
标题: 回复 #2 sratlf 的帖子
S大,流程分析得精彩,不明白的是楼主为何在第二行就写入PAUSE,没有什么特别要求,这一行好像有点多余,请S大指点一下……
作者: sratlf    时间: 2012-2-19 11:44
标题: 回复 #3 jh1688 的帖子
这个得看LZ了  还没看懂LZ要干嘛
作者: sunsea    时间: 2012-2-19 13:31
原帖由 sratlf 于 2012-2-19 11:44 发表
这个得看LZ了  还没看懂LZ要干嘛

是为了测试在::后面的那句严重的语法错误的CMD的反应的
作者: x9tian    时间: 2012-2-19 13:31
理所当然停四次呀, 你不是CALL 吊用了一次么,这有什么好奇怪的
作者: sunsea    时间: 2012-2-19 13:33
顺便问一下,那句ECHO处于关闭状态是怎么冒出来的?
作者: sunsea    时间: 2012-2-19 13:37
最奇怪的是:吧P修改成这样:
  1. @echo off
  2. pause
  3. call :r 0015.3
  4. pause
  5. :r
  6. set hf=%1
  7. ::set hf==A%$d=$!=%t:*=%*=!!%!%=%hf:*=%=?%#%|ECHO YY
  8. ::上面这句有严重的语法错误!
  9. echo %hf%
  10. pause
复制代码
结果第一个pause后就一闪而过了
注掉了还语法错误!
好奇怪!



[ 本帖最后由 2011czmxbb52 于 2012-2-19 13:40 编辑 ]
作者: sratlf    时间: 2012-2-19 13:40
标题: 回复 #7 2011czmxbb52 的帖子
@echo off
pause
call :r 0015.3
pause
:r
set hf=%1
::set hf==%t:*=%*=!!A%$d=$!=%!%=%hf:*^=%=?%#%|ECHO YY
echo %hf%
pause

看流程就知道了
pause
:跳至f标签
set hf=%1
::输出hf值,此时为 0015.3
echo %hf%
pause
::call结束返回原处
pause
::此时%1值为空,等同于set hf= ,即清除变量hf
set hf=%1
::接上句,变量hf已被清除,等同于 echo ,输出echo当前状态,由第一句的echo off,即当前echo处于关闭状态
echo %hf%
pause

::全部结束
作者: sunsea    时间: 2012-2-19 13:41
谢谢S大,不过还有问题,看8楼
作者: sratlf    时间: 2012-2-19 13:50
标题: 回复 #8 2011czmxbb52 的帖子
虽然是被注释掉了  但是在执行时不是直接跳过的  还是会扩展 "%hf:"  因为变量hf存在  扩展就会出错

补充一句:想不出错的话只要改变引号里的四个字符就行了  比如随意加个别的  或者去掉几位  只要不是这个顺序就行了

[ 本帖最后由 sratlf 于 2012-2-19 13:51 编辑 ]
作者: pznpt    时间: 2012-2-19 21:15
S版分析的非常在理。但貌似扩展的是%*(指%0,%1,%2等),只要不让%*解析成功就不会报错。
作者: sratlf    时间: 2012-2-19 21:33
标题: 回复 #12 pznpt 的帖子
你自己试下就知道了

如果扩展指的是 %* 的话  那么为什么将"%hf:*"改为"%haf:*" "%hbf:*" "%f:*" "%h:*" 等等就不报错了呢。。。
作者: pznpt    时间: 2012-2-19 21:47
原帖由 sratlf 于 2012-2-19 21:33 发表
你自己试下就知道了

如果扩展指的是 %* 的话  那么为什么将"%hf:*"改为"%haf:*" "%hbf:*" "%f:*" "%h:*" 等等就不报错了呢。。。


刚试了下,图中的数字就是%*扩展的。至于为什么"%hf:*"改一下就不报错,牵扯到CMD预处理机制,我也不懂啊。


作者: sratlf    时间: 2012-2-19 22:33
标题: 回复 #14 pznpt 的帖子
没看懂... 是说 set hd=0015.3这个吗  这个扩展的是%1  没任何错误  

你可以试着在 set hf=%1 后面加一行 echo %hf% 然后看结果  是可以输出变量hf的值的

因此出错的就是被注释的那行  至于为什么  我同样不知道
作者: pznpt    时间: 2012-2-19 23:53
我是将楼主在8#的代码保存到d:\test.bat,将开头的@echo off注释掉,然后在命令提示符下输入d:\test.bat,运行结果:

::set hf==A%$d=$!=%t:*=%*=!!%!%=%hf:*=%=?%#%|ECHO YY 这一行经CMD预处理解析后,变成图中带红框的那一行。其中红框数字应该是%*扩展后的数字。

即使这一行被注释掉了,set命令不被执行了,但预处理还是会执行的。

[ 本帖最后由 pznpt 于 2012-2-20 00:02 编辑 ]
作者: sratlf    时间: 2012-2-20 14:46
标题: 回复 #16 pznpt 的帖子
错误提示是 “此时不应有 ....”  那一串字符是 %hf:*后面的

从截图中也能看出来  0015.3能显示说明扩展%*成功了  失败的是后面部分
作者: dos时代菜鸟    时间: 2012-2-22 18:01
在 第二个 pause 后面插入一如一行

goto :eof




欢迎光临 无忧启动论坛 (http://bbs.wuyou.net/) Powered by Discuz! X3.3