|
namejm
荣誉版主
       batch fan
积分 5226
发帖 1737
注册 2006-3-10 来自 成都
状态 离线
|
『楼 主』:
[小把戏]交换两个变量的值而不使用临时变量
使用 LLM 解释/回答一下
通用型的:
@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
General type:
@echo off
set var1=abc
set var2=123
echo Before exchange: var1=%var1% var2=%var2%
set var1=%var2%& set var2=%var1%
echo After exchange: var1=%var1% var2=%var2%
pause
If the values of the two variables to be exchanged are numbers, the following two schemes can also be used:
Scheme one:
@echo off
set /a num1=123,num2=456
echo Before exchange: num1=%num1% num2=%num2%
set /a num1=%num2%,num2=%num1%
:: set num1=%num2%& set num2=%num1% is also acceptable
echo After exchange: num1=%num1% num2=%num2%
pause
Scheme two:
@echo off
:: There will be a limit on the value range, that is, the sum of num_a and num_b must be within the range of 2^-31 to 2^31-1
set /a num_a=123,num_b=456
echo Before exchange: 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 After exchange: num_a=%num_a% num_b=%num_b%
pause
|

尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。 |
|
2007-1-25 08:16 |
|
|
PPdos
高级用户
   
积分 783
发帖 268
注册 2006-12-26
状态 离线
|
『第 2 楼』:
被我先抢座了^^
使用 LLM 解释/回答一下
纪录在案 以备后用!~
Record it for future use!~
|

菩提本无树,明镜亦非台,本来无一物,何处惹尘埃. |
|
2007-1-25 08:27 |
|
|
hangyug
初级用户
 
积分 99
发帖 43
注册 2007-1-12
状态 离线
|
『第 3 楼』:
使用 LLM 解释/回答一下
呵呵,试了一下,真是,,,还在琢磨呢。。。
Hehe, tried it, really, ... still thinking about it...
|

我很菜,但我很努力~ |
|
2007-1-25 08:29 |
|
|
0401
中级用户
   带走
积分 435
发帖 88
注册 2005-9-24
状态 离线
|
『第 4 楼』:
使用 LLM 解释/回答一下
不错,巧妙利用环境变量扩充的特性。其实这三个例子应该都算是一个意思吧。
Not bad, making clever use of the feature of environment variable expansion. Actually, these three examples should all be of the same meaning, right?
|
|
2007-1-25 09:02 |
|
|
namejm
荣誉版主
       batch fan
积分 5226
发帖 1737
注册 2006-3-10 来自 成都
状态 离线
|
『第 5 楼』:
使用 LLM 解释/回答一下
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%也存在类似的现象。
Originally posted by 0401 at 2007-1-24 20:02:
Not bad, cleverly using the characteristics of environment variable expansion. In fact, these three examples should all be of the same meaning, right?
If you have carefully looked at the code, you will feel that they are not the same idea: the universal code uses & to exchange the values of two variables. Solution 1 uses some characteristics of set /a. On the basis of using the characteristics of set /a, Solution 2 also uses the formula A+B-A=B, A+B-B=A to exchange the values of variables.
In fact, these几段demonstration codes also lead to a relatively interesting topic: set var1=%var2% has assigned the value of var2 to var1. According to reason, at this time the value of var1 has changed, but when using & to lead to another assignment statement set var2=%var1%, why can var2 still get the value before var1 changed? Does the variable var1 can store more than one value at the same time? set /a num1=num2%,num2=%num1% also has a similar phenomenon.
|

尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。 |
|
2007-1-25 10:11 |
|
|
pengfei
银牌会员
    
积分 1218
发帖 485
注册 2006-7-21 来自 湖南.娄底
状态 离线
|
『第 6 楼』:
使用 LLM 解释/回答一下
交换二个变量值算法非常简单.
假如有两个杯子: 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值展开至赋值语句中了, 因此不用中间变量而交换变量值. 这里解释器扮演了中间变量.
其实真正不用中间变量交换两个变量值, 在二进制程序中也可以实现的方法也有.
就是用位运算来实现的, 呵呵~ 大家想想?
The algorithm to swap the values of two variables is very simple.
Suppose there are two cups: A and B. To swap the water in cups A and B, a third cup C is needed.
1. Pour the water from cup A into cup C;
2. Pour the water from cup B into cup A;
3. Pour the water from cup C into cup A;
In this way, the water in the two cups is swapped.
Among the three methods given by brother namejm, the first one uses the pipe character to swap variables, and the latter two are similar in meaning, using the comma operator to swap variables.
In fact, this method is realized by the particularity of the script. If you are familiar with macros in the C language, it is not difficult to understand. The script is executed by the interpreter. When the batch script interpreter is interpreting, it must first perform macro expansion, and in general, it is interpreted line by line.
set x=2
set y=3
set x=%y%&set y=%x%
Here, the last line is macro-expanded to set x=3&set y=2, and the values of x and y are automatically expanded into the assignment statement, so the values of the variables are swapped without an intermediate variable. Here, the interpreter acts as the intermediate variable.
In fact, there are also methods to swap the values of two variables without using an intermediate variable in binary programs.
That is to use bit operations to achieve it, hehe~ Everyone think about it?
|

业精于勤而荒于嬉,形成于思而毁于随。 |
|
2007-1-25 10:25 |
|
|
qzwqzw
银牌会员
     天的白色影子
积分 2343
发帖 636
注册 2004-3-6
状态 离线
|
『第 7 楼』:
使用 LLM 解释/回答一下
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
Teaching Cases of C Language Textbooks
set /a "a=b^a"
set /a "b=b^a"
set /a "a=b^a"
In addition, four arithmetic operations can also be implemented
Just not as flexible and unrestricted as XOR operation
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 楼』:
使用 LLM 解释/回答一下
是的, 四则运算无论从效率还是使用范围来说都没有位运算那么好.
@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
Yes, in terms of both efficiency and scope of use, the four arithmetic operations are not as good as bitwise operations.
@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 楼』:
使用 LLM 解释/回答一下
在单个语句之中,变量的赋值并不能马上被扩展(引用),只能在下一个语句中才能被扩展。单个语句是指 if for 语句以及使用括号 && & ||等连接的语句。除非启用了环境变量扩展延迟,并且使用“!”来代替“%”才能扩展变量值。所以我才说namejm兄你的三个例子意思差不多。。。
In a single statement, the assignment of a variable cannot be expanded (referenced) immediately; it can only be expanded in the next statement. A single statement refers to if, for statements, and statements connected using parentheses && & ||, etc. Unless environment variable expansion delay is enabled and "!" is used instead of "%" to expand the variable value. So that's why I said that Brother namejm's three examples are similar in meaning...
|
|
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 楼』:
使用 LLM 解释/回答一下
Originally posted by pengfei at 2007-1-24 21:25:脚本靠解释器执行, 批处理脚本解释器在解释时必须先执行宏展开, 并且在一般情况下为一行一行解释.
呵呵,想起了这就是批处理的预处理机制^_^,准确的说法似乎应是 逐句执行。
Originally posted by pengfei at 2007-1-24 21:25:Scripts are executed by an interpreter. When a batch script is interpreted, macro expansion must be performed first, and in general, it is interpreted line by line.
Hehe, reminds me of this is the preprocessing mechanism of batch processing ^_^, the accurate statement seems to be executed line by line.
|

尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。 |
|
2007-1-25 11:17 |
|
|
pengfei
银牌会员
    
积分 1218
发帖 485
注册 2006-7-21 来自 湖南.娄底
状态 离线
|
『第 12 楼』:
使用 LLM 解释/回答一下
是的, 一般情况下为一行一行解释, 应该改为逐句解释执行, 用括号括起来的复合语句, 解释器也是一次执行的.
Yes, generally speaking, it is explained line by line. It should be changed to executed sentence by sentence. For compound statements in parentheses, the interpreter also executes them at one time.
|

业精于勤而荒于嬉,形成于思而毁于随。 |
|
2007-1-25 11:20 |
|
|
lxmxn
版主
       
积分 11386
发帖 4938
注册 2006-7-23
状态 离线
|
『第 13 楼』:
使用 LLM 解释/回答一下
感觉还是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
It feels that what user 0401 on floor 9 said is relatively reasonable. If variable delay is enabled, some of the above examples may not work.
@echo off
set var1=abc
set var2=123
echo Before exchange: var1=%var1% var2=%var2%
set var1=%var2%&call set var2=%%var1%%
echo After exchange: var1=%var1% var2=%var2%
pause
|
|
2007-1-25 13:49 |
|
|
pengfei
银牌会员
    
积分 1218
发帖 485
注册 2006-7-21 来自 湖南.娄底
状态 离线
|
『第 14 楼』:
使用 LLM 解释/回答一下
lxmxn兄用call %%var1%%实际没有展开, 和!var!一样, 是变量延迟的另一种用法. 因此变量交换也无法实现.
Brother lxmxn, using call %%var1%% doesn't actually expand, just like !var!, which is another way of variable delay. Therefore, variable swapping can't be achieved either.
|

业精于勤而荒于嬉,形成于思而毁于随。 |
|
2007-1-26 12:03 |
|
|
htysm
高级用户
   
积分 866
发帖 415
注册 2005-12-4
状态 离线
|
|
2007-1-27 05:33 |
|