set共两个参数/a 与/p
直接键入"set" 会显示系统化境变量及当前环境变量,
而 键入"set p" 会显示所有以字母 P 打头的变量,并且以变量名排序
缺省参数的情况不用多说,注意两点
1.赋空值:
set "a="
2.养成好的习惯,以免多赋值一个空格出错.
比如:
set str=abc
时加上一对双引号
set "str=abc"
对于/a 参数
/A 命令行开关指定等号右边的字符串为被评估的数字表达式。该表达式
评估器很简单并以递减的优先权顺序支持下列操作:
() - 分组
! ~ - - 一元运算符
* / % - 算数运算符
+ - - 算数运算符
<< >> - 逻辑移位
& - 按位“与”
^ - 按位“异”
| - 按位“或”
= *= /= %= += -= - 赋值
&= ^= |= <<= >>=
, - 表达式分隔符
注意前提:
1. 8进制数0?(0<=?<=7)与16进制数0x?(0<=?<=15),首字符不为0者为10进制数.
2. /a参数只对-(2^31-1)至2^31之间整数进行操作(注意是xp版本).
这点可以用代码来测试:- @echo off&setlocal enabledelayedexpansion
- :支持最大数为1.9950631168807583848837421626836e+3010
- set m=1
- for /l %%a in (1 1 10000) do (
- for /l %%b in (1 1 %%a) do (
- set /a m*=2
- set /a n+=1
- echo !m!=2^^^^!n!
- if "!m:~,1!" == "-" echo !m!&set /a mm=!m!-1&echo !mm!=!m!-1 &pause&exit
- ) )
复制代码 一元运算符~ ! -
~取反
将-(2^31-1)至2^31看做一个数轴,"原点O"为0的左侧与-1的右侧
(此数轴可以看做一个首尾封闭的数轴,对2^31-1加1将得到-2^31)
这样可以将计算机里的二进制数(全是整数)的取反看做求"相反数"了:
-2^31 ...︺︺︺︺︺︺︺︺︺︺︺︺︺︺︺O︺︺︺︺︺︺︺︺︺︺︺︺︺︺︺... 2^31-1
... -3 -2 -1 0 1 2 3 ...
~[x]就表示[x]的反数
比如:复制代码 %a%就等于0复制代码 %a%就等于-6
!取非
![非0正数]为0
![0]为1
比如:复制代码 %a%就等于0复制代码 %a%就等于1
"-"取负数
-[x]与数学上的-x是一致的,只是要注意发生溢出时的状况
比如:复制代码 %a%为-2147483648而非2147483648,这是因为2147483648已溢出:
2147483648=(2^31-1)+1
算术运算符 * / % ﹢ -
算术运算符: * / % ﹢ - 分别对应
数学符号: x ÷ mod(取余) + -
需要注意的是"%"是在命令行下,而在bat中则要用%%
逻辑移位: << >>
注意在批处理中或命令行下要加上一对双引号""或用^对<,>进行转义.
set /a [x]"<<"[y]
表示对[x]的二进制数左移[y]位
比如:复制代码 %a%就等于30
这是因为:15=bin(00 00000 00000 00000 00000 00000 01111)
左移1位就成了bin(0 00000 00000 00000 00000 00000 011110)
而bin(0 00000 00000 00000 00000 00000 011110)=2^4+2^3+2^2+2^1=30
经过简单的数学推导就可以知道:
[x]"<<"[y]==[x]*2^[y]
[x]">>"[y]==[x]/2^[y](注意溢出)
同理">>"就是右移,原理一样,这里略.
逻辑 "异", "或", "与": "^", "|", "&"
注意在批处理中或命令行下要在运算符前加上^
这里的: ^ | & 对应于
离散数学上的: 异或⊕ 析取∨ 合取∧
规则: 合取∧(有0则0) 析取∨ (有1则1) 异或⊕ (同0反1)
比如:复制代码 %a%就等于10
这是因为:
01111
⊕) 00101
─────
=) 01010
而bin(01010)=10
对于"|", "&"原理一样,这里略.
赋值运算符
"=" 这个不用说了
对于 *= /= %= += -= &= ^= |= <<= >>
拿"+="为例,其他同理.
这只是一种简写
比如下面两行代码等效:复制代码 表达式分隔符","
这个运算符可以用来简化代码:
比如:- set /a a=1
- set /a b=2
- set /a c+=3
复制代码 就可以简写为:复制代码 - @echo off
- ::分数化小数,徒手除法
- set/a a=1,b=7
- set/a c0=a/b, r0=a%%b*10
- set/a c1=r0/b,r1=r0%%b*10
- set/a c2=r1/b,r2=r1%%b*10
- set/a c3=r2/b,r3=r2%%b*10
- echo %c0%.%c1%%c2%%c3%
- pause
复制代码 另外:
set /a ... 与 set /p ...
可以省略掉set 与 /之间的空格写成
set/a ... 与 set/p ...
关于这类省略空格的用法,还有不少,后续再补充.
set/a的指针用法(有点像指针姑且这么叫吧):
数值定义:- @echo off
- call:arr arr 1 2 3 4 + d d+ 258 68 944 ddd pp dd
- set arr
- pause
- :arr
- set/a n+=1
- if %2.==. goto:eof
- set %1%n%=%2
- shift /2
- goto:arr
复制代码 统计字符串中各种字符出现次数:- @echo off
- set "str=aferefwfwerergrgreaaffwafwa"
- set/p= %str% 中有<nul
- :loop
- set /a %str:~0,1%+=1&set str=%str:~1%&if defined str goto loop
- echo a %a% 个
- pause
复制代码 关于参数/P
1.接收键盘的输入- @echo off
- :begin
- SET /p a=请输入一个字符串:
- echo %a%
- goto begin
复制代码 注意能用来作为变量的字符不能是常量数字,可以是字母,汉字等,及其字符串.
当输入特殊字符^&|<>时,前要加上^,否则出现语法错误.
语句"SET /p a=请输入一个字符串:"
类似c++里的:- cout << "请输入一个字符串:\n";
- cin >> a;
复制代码 2.接收文件的首行.
这个用下面两个代码可以理解%0表示批处理本身:
代码一:- :::::::::::::::::::
- @echo off
- set /p a=<%0
- echo %a%&pause>nul
复制代码 代码二:- ::::::&color 02
- @echo off
- set /p a=<%0
- echo %a%&pause>nul
复制代码 3, set/p 特殊用法 .
左对齐(注意代码中的是制表符):- @echo off&setlocal enabledelayedexpansion
- for /l %%i in (1 10 999) do (set/a n+=1&set /p=^%%i <nul
- if !n!==5 set n=0&echo.
- )
- pause
复制代码 删回车符延迟(也可用ping)显示:- @echo off
- for /f "tokens=*" %%i in (1.txt) do echo.|set /p=%%i
- pause
复制代码 删除1.txt每行的回车符后输出到2.txt里(拼成一行):- @echo off
- for /f "tokens=*" %%i in (1.txt) do set /p=%%i<nul >>2.txt
- pause
复制代码 一般地set /p 的这种用法都会与|或<nul 联系起来.
<nul使得输出的最后一个字符没有换行符,这点很有用. |