|
namejm
荣誉版主
batch fan
积分 5226
发帖 1737
注册 2006-3-10 来自 成都
状态 离线
|
『楼 主』:
[小把戏]交换两个变量的值而不使用临时变量
通用型的:
@echo off
set var1=abc
set var2=123
echo 交换前: var1=%var1% var2=%var2%
set var1=%var2%& set var2=%var1%
echo 交换后: var1=%var1% var2=%var2%
pause 如果要交换的两个变量的值是数字的话,还可以使用如下两种方案:
方案一:
@echo off
set /a num1=123,num2=456
echo 交换前: num1=%num1% num2=%num2%
set /a num1=%num2%,num2=%num1%
:: set num1=%num2%& set num2=%num1% 也是可以的
echo 交换后: num1=%num1% num2=%num2%
pause 方案二:
@echo off
:: 会有数值范围的限制,即 num_a 与 num_b 的和必须在2^-31~2^31-1这个范围内
set /a num_a=123,num_b=456
echo 交换前: num_a=%num_a% num_b=%num_b%
set /a num_a=%num_a%+%num_b%-%num_a%,num_b=%num_a%+%num_b%-%num_b%
echo 交换后: num_a=%num_a% num_b=%num_b%
pause
|
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。 |
|
2007-1-25 08:16 |
|
|
PPdos
高级用户
积分 783
发帖 268
注册 2006-12-26
状态 离线
|
『第
2 楼』:
被我先抢座了^^
纪录在案 以备后用!~
|
菩提本无树,明镜亦非台,本来无一物,何处惹尘埃. |
|
2007-1-25 08:27 |
|
|
hangyug
初级用户
积分 99
发帖 43
注册 2007-1-12
状态 离线
|
『第
3 楼』:
呵呵,试了一下,真是,,,还在琢磨呢。。。
|
我很菜,但我很努力~ |
|
2007-1-25 08:29 |
|
|
0401
中级用户
带走
积分 435
发帖 88
注册 2005-9-24
状态 离线
|
『第
4 楼』:
不错,巧妙利用环境变量扩充的特性。其实这三个例子应该都算是一个意思吧。
|
|
2007-1-25 09:02 |
|
|
namejm
荣誉版主
batch fan
积分 5226
发帖 1737
注册 2006-3-10 来自 成都
状态 离线
|
『第
5 楼』:
Quote: | Originally posted by 0401 at 2007-1-24 20:02:
不错,巧妙利用环境变量扩充的特性。其实这三个例子应该都算是一个意思吧。 |
|
如果你仔细看了代码的话,你就会觉得它们并不是同一种思路:通用型的代码利用了 & 来交换两个变量的值,方案一利用了 set /a 的一些特性,方案二在利用 set /a 的特性的基础上,还使用了A+B-A=B、A+B-B=A这个算式来交换变量的值。
其实,这几段演示代码还引出了一个比较有趣的话题:set var1=%var2%已经把var2的值赋给var1了,按理说,此时var1的值已经发生了改变,但是,在使用 & 引出另一个赋值语句 set var2=%var1% 的时候,为什么var2还能得到var1发生改变前的值?难道var1这个变量能同时保存一个以上的值吗?set /a num1=num2%,num2=%num1%也存在类似的现象。
|
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。 |
|
2007-1-25 10:11 |
|
|
pengfei
银牌会员
积分 1218
发帖 485
注册 2006-7-21 来自 湖南.娄底
状态 离线
|
『第
6 楼』:
交换二个变量值算法非常简单.
假如有两个杯子: A和B, 要将A,B杯子中的水互换, 就要用到第三个杯子C了.
1. 将A杯的水倒入C杯;
2. 将B杯的水倒入A杯;
3. 将C杯的水倒入A杯;
这样就完成了二个杯子中的水的互换. namejm兄给出的三种方法中, 第一种利用管道符交换变量,后两种是差不多的意思, 用逗号运算符来交换变量.
其实这种方法是利用脚本的特殊性实现的, 如果大家熟悉C语言中宏的话就不难理解了. 脚本靠解释器执行, 批处理脚本解释器在解释时必须先执行宏展开, 并且在一般情况下为一行一行解释.
set x=2
set y=3
set x=%y%&set y=%x%
这里最后一句宏展开为set x=3&set y=2, 自动将x与y值展开至赋值语句中了, 因此不用中间变量而交换变量值. 这里解释器扮演了中间变量. 其实真正不用中间变量交换两个变量值, 在二进制程序中也可以实现的方法也有.
就是用位运算来实现的, 呵呵~ 大家想想?
|
业精于勤而荒于嬉,形成于思而毁于随。 |
|
2007-1-25 10:25 |
|
|
qzwqzw
银牌会员
天的白色影子
积分 2342
发帖 635
注册 2004-3-6
状态 离线
|
『第
7 楼』:
C语言教材的教学案例
set /a "a=b^a"
set /a "b=b^a"
set /a "a=b^a" 另外,四则运算也可以实现
只是没有异或运算灵活无限制
set /a a=a+b
set /a b=a-b
set /a a=a-b
|
|
2007-1-25 10:41 |
|
|
pengfei
银牌会员
积分 1218
发帖 485
注册 2006-7-21 来自 湖南.娄底
状态 离线
|
『第
8 楼』:
是的, 四则运算无论从效率还是使用范围来说都没有位运算那么好.
@echo off
set a=2
set b=3
echo a=%a% b=%b%
set /a "a=b^a"
set /a "b=b^a"
set /a "a=b^a"
echo a=%a% b=%b%
set /a a=a+b
set /a b=a-b
set /a a=a-b
echo a=%a% b=%b%
pause
|
业精于勤而荒于嬉,形成于思而毁于随。 |
|
2007-1-25 10:46 |
|
|
0401
中级用户
带走
积分 435
发帖 88
注册 2005-9-24
状态 离线
|
『第
9 楼』:
在单个语句之中,变量的赋值并不能马上被扩展(引用),只能在下一个语句中才能被扩展。单个语句是指 if for 语句以及使用括号 && & ||等连接的语句。除非启用了环境变量扩展延迟,并且使用“!”来代替“%”才能扩展变量值。所以我才说namejm兄你的三个例子意思差不多。。。
|
|
2007-1-25 10:59 |
|
|
simazhuo
新手上路
积分 1
发帖 2
注册 2006-12-31
状态 离线
|
|
2007-1-25 11:07 |
|
|
namejm
荣誉版主
batch fan
积分 5226
发帖 1737
注册 2006-3-10 来自 成都
状态 离线
|
『第
11 楼』:
Quote: | Originally posted by pengfei at 2007-1-24 21:25:脚本靠解释器执行, 批处理脚本解释器在解释时必须先执行宏展开, 并且在一般情况下为一行一行解释. |
|
呵呵,想起了这就是批处理的预处理机制^_^,准确的说法似乎应是 逐句执行。
|
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。 |
|
2007-1-25 11:17 |
|
|
pengfei
银牌会员
积分 1218
发帖 485
注册 2006-7-21 来自 湖南.娄底
状态 离线
|
『第
12 楼』:
是的, 一般情况下为一行一行解释, 应该改为逐句解释执行, 用括号括起来的复合语句, 解释器也是一次执行的.
|
业精于勤而荒于嬉,形成于思而毁于随。 |
|
2007-1-25 11:20 |
|
|
lxmxn
版主
积分 11386
发帖 4938
注册 2006-7-23
状态 离线
|
『第
13 楼』:
感觉还是9楼的 0401 说得比较在理,如果启用变量延迟,以上的某些示例可能不成立。
@echo off
set var1=abc
set var2=123
echo 交换前: var1=%var1% var2=%var2%
set var1=%var2%&call set var2=%%var1%%
echo 交换后: var1=%var1% var2=%var2%
pause
|
|
2007-1-25 13:49 |
|
|
pengfei
银牌会员
积分 1218
发帖 485
注册 2006-7-21 来自 湖南.娄底
状态 离线
|
『第
14 楼』:
lxmxn兄用call %%var1%%实际没有展开, 和!var!一样, 是变量延迟的另一种用法. 因此变量交换也无法实现.
|
业精于勤而荒于嬉,形成于思而毁于随。 |
|
2007-1-26 12:03 |
|
|
htysm
高级用户
积分 866
发帖 415
注册 2005-12-4
状态 离线
|
|
2007-1-27 05:33 |
|