[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
本帖最后由 batman 于 2011-4-23 11:21 编辑

再次测试(测试前猜想变量减少时,变量的内存存储开始地址不会改变)
代码:
  1. @echo off&setlocal enabledelayedexpansion
  2. del /q db-*.txt
  3. call :lp 1 100 random
  4. call :lp 10 20
  5. del /q db
  6. goto :eof
  7. :lp
  8. for /l %%a in (%1,1,%2) do set "_%%a=!%3!"
  9. (echo d2cl2
  10. echo q
  11. echo,
  12. )>db
  13. (for /f "skip=1 tokens=2,3" %%a in ('debug^<db') do (
  14.      echo d%%b%%a:0380&echo q&echo,
  15. ))>tem
  16. del /q db&ren tem db
  17. debug<db>db-%1.txt
  18. start db-%1.txt
复制代码
db-1.txt
  1. -d0DCC:0380
  2. 0DCC:0380  00 5F 31 3D 31 34 37 36-32 00 5F 31 30 3D 35 35   ._1=14762._10=55
  3. 0DCC:0390  37 37 00 5F 31 30 30 3D-32 31 31 35 33 00 5F 31   77._100=21153._1
  4. 0DCC:03A0  31 3D 37 37 35 35 00 5F-31 32 3D 31 35 35 38 36   1=7755._12=15586
  5. 0DCC:03B0  00 5F 31 33 3D 31 30 38-31 00 5F 31 34 3D 38 38   ._13=1081._14=88
  6. 0DCC:03C0  34 39 00 5F 31 35 3D 34-34 35 31 00 5F 31 36 3D   49._15=4451._16=
  7. 0DCC:03D0  31 32 39 34 35 00 5F 31-37 3D 32 35 37 33 35 00   12945._17=25735.
  8. 0DCC:03E0  5F 31 38 3D 31 33 30 31-31 00 5F 31 39 3D 32 37   _18=13011._19=27
  9. 0DCC:03F0  39 39 35 00 5F 32 3D 31-37 31 31 33 00 5F 32 30   995._2=17113._20
  10. -q
复制代码
db-10.txt
  1. -d0DCC:0380
  2. 0DCC:0380  00 5F 31 3D 31 34 37 36-32 00 5F 31 30 30 3D 32   ._1=14762._100=2
  3. 0DCC:0390  31 31 35 33 00 5F 32 3D-31 37 31 31 33 00 5F 32   1153._2=17113._2
  4. 0DCC:03A0  31 3D 32 37 37 36 30 00-5F 32 32 3D 33 37 36 35   1=27760._22=3765
  5. 0DCC:03B0  00 5F 32 33 3D 31 33 30-37 35 00 5F 32 34 3D 37   ._23=13075._24=7
  6. 0DCC:03C0  35 38 38 00 5F 32 35 3D-31 31 31 30 36 00 5F 32   588._25=11106._2
  7. 0DCC:03D0  36 3D 32 33 36 38 35 00-5F 32 37 3D 31 32 37 38   6=23685._27=1278
  8. 0DCC:03E0  39 00 5F 32 38 3D 32 30-33 30 31 00 5F 32 39 3D   9._28=20301._29=
  9. 0DCC:03F0  32 31 39 35 31 00 5F 33-3D 31 35 32 32 00 5F 33   21951._3=1522._3
  10. -q
复制代码
可见当变量减少时(部分变量被清空),其实就是对已有变量进行读取操作时,内存确实不会重新洗牌。
***共同提高***

TOP

8# plp626


当然了,set /a 要把字符串类型转换成数字类型。这里是快了,如果后面的这个变量要参与数学计算的话,通过set设置的字符串还是需要再次转换成数字类型的,这样时间就扯平了。变量一般只设置一次,但是这个变量可能参与多次数学计算的话,很明显set /a  设置的数字类型将更有优势。

TOP

89# applba


批处理存储在内存的变量是否有数据类型之分呢?这又是一个分歧点,有得闹了

TOP

人呢人呢?
这种版主级的舌战正是我所乐见的,向往了这么久,难得碰到一两次,怎么才讨论了一晚上+一上午就停火了...
问题还没解决呐...疑点还很多,举几个例子:
一、究竟是一张表还是N张表?子疑点:
1、系统变量与用户变量的关系,当用户变量覆盖系统变量时,系统变量去哪了?
2、setlocal后的变量是否和setlocal前的变量放在一张表里,并且一起按ansi排序呢?
二、变量存储时是否区分数据类型?
三、只感觉还有些问题迷迷糊糊,但没能抓住思绪,因此下文待续...

TOP

本帖最后由 cjiabing 于 2011-4-23 13:15 编辑
80# batman


1,用来说明微软为什么使用全字符ANSI来排列变量名。
2,命令解释器进内存中的环境变量区间是如何匹配的,是拿着变量名一个一个的遍历所有变量名来比较,还是按着ANSI顺序逐字比较变量名。
hanyeguxing 发表于 2011-4-23 10:20

      还是兄科学发展观学得好,不懂他们鼓捣出什么“真理”出来没有!~
      既然是“变量机制”,至少得出个有现实意义的结论,好指导我们平时怎么设置变量。
      比如用 !var! 还是用 %var% ,用不同的变量还是用同一个变量,用%abc% 顺序的,还是%zijizuodepichulibianliangjizhi%冗长颠倒的变量,用变量还是用临时文件,用多个不同变量,还是用同一个变量……
      再问深一点的:变量是怎么来的?它的作用是什么?它的运行机制是什么?它在内存中是怎么样工作的?变量是如何赋值和如何取消的?微软是怎么解释的?微软是怎么使用变量的?变量与什么有关?变量的极限是什么?有没有最佳和最差变量?有没有系统内部通用变量?怎么区分和联系各种变量?批处理的变量是否可以超出cmd.exe?计算机编码和进制对变量有什么影响?变量在解释器中如何解释?……
寂寞是黑白的,但黑白不是寂寞,是永恒。BAT 需要的不是可能,而是智慧。

TOP

本帖最后由 batman 于 2011-4-23 13:44 编辑

还是测试说明问题,但也带来了新问题。。。。
代码:
  1. @echo off&setlocal enabledelayedexpansion
  2. for /l %%a in (1,1,100) do set "d=!d!&echo d"
  3. call :lp _str a
  4. call :lp _str b setlocal endlocal
  5. call :lp _str s
  6. del /q db&pause
  7. goto :eof
  8. :lp
  9. %3
  10. if "%2" neq "s" set "%1=%2"
  11. (echo d2cl2
  12. echo q
  13. echo,
  14. )>db
  15. (for /f "skip=1 tokens=2,3" %%a in ('debug^<db') do (
  16.      echo d%%b%%a:0000%d%&echo q&echo,
  17. ))>tem
  18. del /q db&ren tem db
  19. for /f "delims=" %%a in ('debug^<db^|findstr /i "%1="') do echo %%a
  20. echo,
  21. %4
复制代码
结果:
  1. 0DBD:0640  5F 53 54 52 3D 61 00 42-4C 41 53 54 45 52 3D 41   _STR=a.BLASTER=A
  2. 0DBD:0640  5F 53 54 52 3D 62 00 42-4C 41 53 54 45 52 3D 41   _STR=b.BLASTER=A
  3. 0DBD:0640  5F 53 54 52 3D 61 00 42-4C 41 53 54 45 52 3D 41   _STR=a.BLASTER=A
  4. Press any key to continue . . .
复制代码
上面的测试表明,setlocal前以及setlcoal-endlocal中以及endlocal后_str变量在内存中储存的地址没有改变(至少是开始值没有改变)。同时说明了cmd中为什么变量名不分大小写,因为不管变量中的字符是不是大小写,内存中统一是以大写的字符储存的变量。但这里又有一个问题了,既然内存中只会储存一个名为_str的变量,那么endlocal后这个变量的值又是怎么恢复为前面的值的,难道还有一个临时储存变量的地方?
***共同提高***

TOP

测试系统变量:
  1. @echo off&setlocal enabledelayedexpansion
  2. for /l %%a in (1,1,100) do set "d=!d!&echo d"
  3. call :lp os
  4. call :lp os a setlocal endlocal
  5. call :lp os
  6. del /q db&pause
  7. goto :eof
  8. :lp
  9. %3
  10. if "%2" neq "" set "%1=%2"
  11. (echo d2cl2
  12. echo q
  13. echo,
  14. )>db
  15. (for /f "skip=1 tokens=2,3" %%a in ('debug^<db') do (
  16.      echo d%%b%%a:0000%d%&echo q&echo,
  17. ))>tem
  18. del /q db&ren tem db
  19. for /f "delims=" %%a in ('debug^<db^|findstr /i "%1="') do echo %%a
  20. echo,
  21. %4
复制代码
  1. 0DBD:03F0  52 4F 43 45 53 53 4F 52-53 3D 32 00 4F 53 3D 57   ROCESSORS=2.OS=W
  2. 0DBD:03F0  52 4F 43 45 53 53 4F 52-53 3D 32 00 4F 53 3D 61   ROCESSORS=2.OS=a
  3. 0DBD:03F0  52 4F 43 45 53 53 4F 52-53 3D 32 00 4F 53 3D 57   ROCESSORS=2.OS=W
  4. Press any key to continue . . .
复制代码
系统变量os在setlcoal-enlocal中去哪里了?,假如将os改成path,运行结果如下:
  1. 0DBD:0400  69 6E 64 6F 77 73 5F 4E-54 00 50 41 54 48 3D 43   indows_NT.PATH=C
  2. 'debug' is not recognized as an internal or external command,
  3. operable program or batch file.
  4. 'debug' is not recognized as an internal or external command,
  5. operable program or batch file.
  6. 0DBD:0400  69 6E 64 6F 77 73 5F 4E-54 00 50 41 54 48 3D 43   indows_NT.PATH=C
  7. Press any key to continue . . .
复制代码
在重新设定path后,debug命令变得无效。
***共同提高***

TOP

“在重新设定path后,debug命令变得无效。”
debug是外部命令,path变量一改变就找不到文件了

TOP

还是测试说明问题,但也带来了新问题。。。。
代码:
@echo off&setlocal enabledelayedexpansion
for /l %%a in (1,1,100) do set "d=!d!&echo d"
call :lp _str a
call :lp _str b setlocal endlocal
call : ...
batman 发表于 2011-4-23 13:32


有一点大家想过么?

call的话就有堆栈,有堆栈在内存中是否影响变量的赋值耗时?

昨晚我就用call,当然也和设置的变量数过少有关,得出的结论让我迷路。。。

TOP

从大量的测试推断cmd.exe在每次运行时就会用以下命令向内存写入信息从而来设置环境变量:
  1. set "ALLUSERSPROFILE=C:\Documents and Settings\All Users"
  2. set "APPDATA=C:\Documents and Settings\Administrator\Application Data"
  3. set "CommonProgramFiles=C:\Program Files\Common Files"
  4. set "COMPUTERNAME=PC-200901071258"
  5. set "ComSpec=C:\WINDOWS\system32\cmd.exe"
  6. set "FP_NO_HOST_CHECK=NO"
  7. set "HOMEDRIVE=C:"
  8. set "HOMEPATH=\Documents and Settings\Administrator"
  9. set "LOGONSERVER=\\PC-200901071258"
  10. set "NUMBER_OF_PROCESSORS=2"
  11. set "OS=Windows_NT"
  12. set "Path=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\Common Files\Thunder Network\KanKan\Codecs;C:\Program Files\StormII\Codec;C:\Program Files\StormII"
  13. set "PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH"
  14. set "PROCESSOR_ARCHITECTURE=x86"
  15. set "PROCESSOR_IDENTIFIER=x86 Family 15 Model 107 Stepping 2, AuthenticAMD"
  16. set "PROCESSOR_LEVEL=15"
  17. set "PROCESSOR_REVISION=6b02"
  18. set "ProgramFiles=C:\Program Files"
  19. set "PROMPT=$P$G"
  20. set "SESSIONNAME=Console"
  21. set "SystemDrive=C:"
  22. set "SystemRoot=C:\WINDOWS"
  23. set "TEMP=C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp"
  24. set "TMP=C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp"
  25. set "USERDOMAIN=PC-200901071258"
  26. set "USERNAME=Administrator"
  27. set "USERPROFILE=C:\Documents and Settings\Administrator"
  28. set "windir=C:\WINDOWS"
复制代码
***共同提高***

TOP

95# zm900612
我说的就是这个意思,只是没有说明罢了,呵呵。。。
***共同提高***

TOP

本帖最后由 zm900612 于 2011-4-23 15:05 编辑

99# plp626


我理解错了...而且初中高中的数学,我都没怎么听课,喜欢用自己的方法东拼西凑解题

98# batman


噢,怪不得,我还纳闷老兄怎么可能把这忘了


这话题越来越好玩了,斑竹们继续吵架,我是跑龙套的群众演员,等结果

TOP

本帖最后由 hanyeguxing 于 2011-4-24 06:18 编辑

运行批处理时,命令解释器就复制了系统环境变量进入本地,这些系统变量也就本地化了,而 set 的都是本地,所以用set 也只改变本地环境变量
打个比方,系统变量为其他位置的一个源文件,系统变量本地化就像为他在当前目录创建快捷方式,快捷方式可以随意访问源文件。
而 set 这些本地化的系统变量就相当于修改了快捷方式名称,如何修改都不会改变源文件的名称
寒夜孤星:在没有说明的情况下,本人所有代码均运行在 XP SP3 下 (有问题请发贴,QQ临时会话已关闭)

TOP

那清空了本地化操作之后呢?命令解释器是再次复制系统变量进入本地吗?
还有setlocal呢?前后都是本地化操作,为什么endlocal之后能还原上一个setlocal之后的操作呢?

TOP

百度搜索下:变量、环境变量、全局变量、局部变量、静态变量、变量名污染、堆栈……
内容虽然不是很多,可能与批处理也无关,不过一些观点还是值得参考的!~
寂寞是黑白的,但黑白不是寂寞,是永恒。BAT 需要的不是可能,而是智慧。

TOP

返回列表