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

[原创] [批处理命令一日一教学 续](45)注释语句:rem和::

【原】[一日一教学]批处理系列帖子索引 http://bbs.bathome.net/thread-2576-1-1.html
【续】[一日一教学]批处理系列帖子索引 http://bbs.bathome.net/thread-13798-1-1.html


帮助信息:
  1. 在批处理文件或 CONFIG.SYS 里加上注解或说明。
  2. REM [comment]
复制代码
命令概括:
rem,全英文remark(不确定),意为:注释。
comment,全英文comment,意为:评论、意见;这里可引申为注释。

参数详解:
程序员代码编写规范的三点之一:
1.代码层次分明,善用tab加以缩进。
2.尽量做到让变量名、标签名、函数名“见名知意”!
3.适当的注释。

批处理虽然只是脚本,但脚本也是语言,也有作为脚本语言的尊严,所以rem可以有、::也可以有。

rem和::用处一样,也可以看成是一物两名,就像毛润之、石三伢子同指本朝太祖爷一样。

rem有什么用呢?
有道词典给出了rem的解释:指定由DOS忽略的命令行。
这解释算是贴切,其实所有的编程语言的注释语句都是这样,将注释后的语句忽略,使之无效化。

不加rem前。
例如:
  1. @echo off
  2. echo 你好,这套教程你觉得怎样呢?
  3. pause>nul
复制代码
效果:
  1. 你好,这套教程你觉得怎样呢?
复制代码
加上rem后。
例如:
  1. @echo off
  2. rem echo 你好,这套教程你觉得怎样呢?
  3. pause>nul
复制代码
  1. @echo off
  2. :: echo 你好,这套教程你觉得怎样呢?
  3. pause>nul
复制代码
效果都是:


echo message 被忽略、无效化了。


扩展阅读:
1.为什么要注释?
注释不仅有利于别人读懂你的程序,也有利于日后的自己读懂你的程序。
这其中的道理你也可以反证,编程的规范化是所有程序员默默遵守的准则,若然没有其可取之处,那么他们为什么遵守呢?所有的程序设计语言为什么都有注释语句呢?


2.在什么地方注释?
在for之类的复合语句中对语句注释;
在for之类的复合语句之前对整个复合语句注释;
在源程序开始处,对整个程序注释——说明程序的功能;

总原则:如果不注释,理解起来就会很困难,或者虽无困难,但浪费时间;

3.批处理中的特殊“注释符”。
标签注释。
例如:
  1. @echo off
  2. : echo 你好,这套教程你觉得怎样呢?
  3. pause>nul
复制代码
变量注释。
例如:
  1. @echo off
  2. %echo 你好,这套教程你觉得怎样呢?%
  3. pause>nul
复制代码
3.多行注释。
例如:
  1. @echo off
  2. rem a^
  3. b^
  4. c
  5. pause>nul
复制代码
附件: 您需要登录才可以下载或查看附件。没有帐号?注册
1

评分人数

不错不错不错不错不错
1

评分人数

    • CrLf: 最后一次警告,不要灌水PB -10

TOP

回复 24# Cathon


    奥,在ECHO的本行后面加注释要用个&符。(新手)

TOP

我今天刚发现注释不能放在ECHO后面,否则注释无效。
ECHO的下一行是‘)’时,括号的后面也不能加注释,否则闪退。
(我是新手)

TOP

本帖最后由 shelluserwlb 于 2014-11-6 14:21 编辑

多行注释示例1:
@echo off
goto start
释注内容
释注内容
释注内容
......
:start


多行注释示例2:
@echo off
rem ^
释注内容^
释注内容^
释注内容^
........^
释注内容

注:第2种方法注释内容最后一行最末尾没有转义字符^。
      这里的转义字符可以简单地理解为将下一行和本行连接起来形成一个语句;
      每行注释语句之间不能有超过一行的空行,否则就需要在空行中另加^才行。
例如:
@echo off
rem ^
释注内容^
释注内容^

释注内容^

^

释注内容
echo 这是一个测试
pause

TOP

嗯,不错,比较严格

TOP

回复  CrLf
    :: 本质上是无效标签?我一直以为是注释符,(跟@具备将后面的语句括起的功能一样)只 ...
Hello123World 发表于 2011-8-30 18:38

:: 本质上是无法被goto到的空标签
因为:作为标签的Delims
使标签的Token变成空值
而goto的语法检查是不允许有“空标签”的
因此它可以被用作注视用途

详细讨论见这里
http://www.cn-dos.net/forum/view ... ghlight=&page=2
天的白色影子

TOP

对不起,CrLf,我错了!在将echo后的文字改为全ASCII字符后,脚本确实能正常运行。出现上面的错误大概是编码的问题吧。

TOP

回复 18# CrLf

        我同意将回车换行当成一个字符看待,这和我们的实际操作也是相符的,即每行结束转入下一行只需按一次回车键。你说“整个脚本中即使只有0A换行符也一样能执行”,我的理解是脚本源代码中即使行末只有0A,脚本也能正常工作。不知是不是这个意思?为此,我在UE中写了两句代码:
  1. @echo off
  2. echo 只认0A
复制代码
然后将第一行后的0D删除,保存后运行提示出错:
'ho' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
出错倒在我的意料之中,但命令怎么变成了'ho',这却让人伤神了。
删除0D后的脚本在UE和记事本中效果如图:

删除0D后的脚本:

敬请验证。

TOP

回复 17# smbee


    cmd 换行时只认 0A,碰到 0D 0A 时将剔除此处的 0D,其实整个脚本中即使只有 0A 换行符也是一样能执行的。因此在分析的时候,不妨把 0D 0A 的组合视为单独的一个 0A,或许会有新的解释?

TOP

关于行末转义符的个人猜想
  看了楼主的教程,对于多行注释又学到了一招,以前只知道利用goto来进行多行注释。呵呵,感谢楼主为知识传播所付出的辛劳!
  此后看了各位朋友们对行末转义符的工作原理探讨,我也同楼主一样对行末转义符后连续空两行便不再工作感到困惑,另Jookin兄所说的行末是换行回车做为结束符号是不对的。因为我用16进制编辑器打开任一Windows中的文本类型文件(txt,cmd,vbs……)均看到行结束符号是0D 0A,即回车换行!
  受此启发,我将以下代码的输出重定向到一文本文件中后用UE打开查看其16进制时发现了一个有趣的现象。
  1. @echo off
  2. echo 1st:
  3. echo a^
  4. b
  5. echo.
  6. echo.
  7. echo.
  8. echo 2nd:
  9. echo a^
  10. b
  11. echo.
  12. echo.
  13. echo  3rd:
  14. echo a^
  15. b
  16. echo.
  17. echo.
  18. echo.
  19. echo 4th:
  20. echo a^
  21. ^
  22. b
复制代码
代码中之所以要增加若干空行是为了在16进制模式下各情况的输出结果能对齐,下面给出输出结果及在UE中打开查看其16进制的图片。

请大家注意看其16进制模式。
  情况1:a与b首尾相接。从结果看第3行的转义符将其后的回车换行符“删除”了。b后面的第一对回车换行是输出时正常产生的,后面的三对则是三条echo.产生的。
  情况2:a的后面是0A,所以输出结果表现为a,b各占一行。这就是说第9行的转义符将原来总共2对即4个(0D 0A 0D 0A)回车换行符“删除”了前三个。b后面的三对回车换行符解释同情况1。最后的空格(20)是我特意在“3rd”的前面加上的,以便三种情况对齐后分析。
  情况3:a的后面同样是0A,至于后面的4对回车换行符则是正常输出及第19、20、21行产生的。第17为空不会产生任何输出,第18行执行出错,也不会在此文件中产生输出。是不是也同情况2一样第15行的转义符将其后的4个回车换行符“删除”了三个,只留下最后一个呢?

  至此,我得出这样一个猜想:行末转义符将其后的回车换行符整体转义形成一个新的“转义”符,这个新的“转义”符对其后的回车符进行“转义”时将其“转义”为空(不是ASCII码为0的那个空,而是什么都没有的空。通俗地讲就是把回车符吃了,然后消失在人海。),或者说对其后的一对回车换行符“转义”为换行符(0A),而其它字符则原样输出。
  情况4验证了我的猜想。a后面的两个换行符(0A)分别由23、25行的转义符产生。
  以上猜想纯属个人见解,不对之处还请大家指正。
1

评分人数

    • CrLf: 有想法技术 + 1

TOP

转义符^在行末时,只有最近的一行起作用
  1. echo;^
  2. &call :Colour
复制代码
寂寞是黑白的,但黑白不是寂寞,是永恒。BAT 需要的不是可能,而是智慧。

TOP

本帖最后由 JooKin 于 2011-9-19 20:43 编辑

回复 14# Hello123World


    不是的,执行完第3行(严格来说应该是第2行,因为^的存在原来的第3行已经接上第2行的末尾成为一行了)已经结束了。看下面的两个例子就明白了:
  1. ::例1
  2. @echo off
  3. echo Hey,Hello123World!
  4. pause
复制代码
结果:
  1. Hey,Hello123World!
  2. 请按任意键继续. . .
复制代码
  1. ::例2
  2. @echo off
  3. echo Hey,Hello123World!^
  4. pause
复制代码
结果:
  1. Hey,Hello123World!
  2. 请按任意键继续. . .
复制代码
第2个例子只是在第2行末尾加了个^,为什么结果会多一个空行?因为加了^后,第3行的\n\r接上了第2行的末尾,跟第2行成为1行了,此时的第3行的位置已经是原来第4行的\n\r了。这个时候执行完第2行,因为末尾有原来的第三行的\n\r,所以到此就结束了。接下来就轮到执行第3行的内容了,并且是另起一行(这个应该不用解释了,因为上一行有\n存在),但是因为第3行只有\n\r(原来第4行的\n\r)了,没有任何命令,所以造成的结果就是执行第4行的pause的时候又另起一行了,很明显是因为第3行的\n的缘故,所有整个结果跟第1个例子相比就是中间多出了\n\r(原来第4行的\n\r),即空行。

还有就是连续的多个\n\r只有一个起作用,再结合前面两个例子看:
  1. @echo off
  2. echo Hey,Hello123World!^
  3. pause
复制代码

TOP

回复 13# JooKin

你说的其它的都对,比如以/n/r(换行回车)结尾,/n(换行)在前
例如:
  1. @echo off
  2. echo a^
  3. b
  4. pause>nul
复制代码
结果是
  1. ab
复制代码
这点有力的证明^确实转义的是换行符。

   受益很多, 感谢你的回复。我还是不能理解,按你说的
cmd以换行回车为一条命令的结束标志是相符的

那么
  1. @echo off\n\r
  2. echo a^\n\r
  3. \n\r
  4. ^\n\r
  5. b^\n\r
  6. \n\r
  7. ^\n\r
  8. c\n\r
  9. pause>nul
复制代码
这里为什么没有在第3行就结束,第3行不是有个换行回车吗?

TOP

本帖最后由 JooKin 于 2011-9-18 20:37 编辑

回复 12# Hello123World


    可能是abcdshenji笔误,windows系统里正确的应该是换行符在前,回车符在后,即\n\r。unix系统里只有换行符\n。所以应该是:
  1. @echo off\n\r
  2. echo a^\n\r
  3. \n\r
  4. ^\n\r
  5. b^\n\r
  6. \n\r
  7. ^\n\r
  8. c\n\r
  9. pause>nul
复制代码
当第一次^后,转义了换行符,只有回车符起作用,所以接上第3行的\n\r,此时是占据一行的,如果没有碰到第4行的^,结果将是:
  1. a\n\r
  2. \n\r               //这里是第4行的\n\r
复制代码
这个效果就是:
  1. a
复制代码
也就是说,执行完第4行的\n\r的时候是打一个空行,等到执行到第5行b^\n\r的时候,因为前面有了第4行末尾的\n\r,所以cmd就会认为新的命令开始了,这跟cmd以换行回车为一条命令的结束标志是相符的。所以
  1. 'b' 不是内部或外部命令,也不是可运行的程序
  2. 或批处理文件。
复制代码
就解释的通了,因为b当然不是什么命令。如果第4行加了^,就跟前面的:
  1. @echo off
  2. echo a^
  3. b^
  4. c
  5. pause>nul
复制代码
同一个道理了,因为加了^之后第4行就没有换行符了,所以就接上第5行的b^\n\r,此时还是占据一行,所以结果就是:
  1. a^\n\r                        //这里是第3行的\n\r
  2. b^\n\r                       //这里原来是第4行,现在第5行的b^\n\r接上去了
复制代码
所以效果就是:
  1. a
  2. b
复制代码
首先你要明白的就是换行符负责把字符串向下移一行,回车符负责把开始打印的位置放到字符串的开头

TOP

返回列表