什么是变量交换
变量交换(Swapping Variables)指的是将两个变量中存储的值互换。交换前a存储的值交给b,b存储的值交给a。
例如:a = 20, b = 30,交换后变成a = 30, b = 20。
这个操作在排序算法(如冒泡排序、快速排序)、数据重排、临时状态切换等场景中经常出现。虽然看起来简单,但理解交换的不同实现方式对掌握编程思维有帮助。
核心实现逻辑
交换两个变量的值,常见的有两类方法:
方法一(借助第三个变量):用临时变量暂存a的值,然后把b的值赋给a,之后把临时变量中暂存的值赋给b。这种方法思路直观,适合任何数据类型。
方法二(不使用第三个变量):通过算术运算(加减或乘除)在两个变量之间传递数值。这种方法不需要额外内存,但有适用范围限制——只适用于数字类型,且要避免某些边界问题。
个人经验:在项目中,我看过的代码里绝大多数用的都是临时变量法。不是因为算术法不好,而是因为它更容易读,不容易出错。代码是写给人看的,才是给机器执行的。
示例一:使用第三个变量交换
这是代码号学习编程中最基础也最常见的交换方式。
<?php
$a = 45;
$b = 78;
// 交换过程
$temp = $a; // 把a的值暂存到temp
$a = $b; // 把b的值赋给a
$b = $temp; // 把temp中原来的a值赋给b
echo "交换后的结果:<br>";
echo "a = " . $a . ", b = " . $b;
?>
输出:
交换后的结果:
a = 78, b = 45
关于临时变量的命名:$temp、$tmp、$t都是常见的写法,意思都是临时(temporary)。团队协作时建议用$temp,可读性更好。
示例二:使用加减运算交换(不借助第三个变量)
这个方法通过加减法在两个变量之间传递数值,整个过程不需要额外变量。
<?php
$a = 234;
$b = 345;
// 交换过程(加减法)
$a = $a + $b; // 第一步:a变成两数之和
$b = $a - $b; // 第二步:b变成原来的a值
$a = $a - $b; // 第三步:a变成原来的b值
echo "a = {$a}<br>";
echo "b = {$b}<br>";
?>
输出:
a = 345
b = 234
运算过程拆解(假设初始a=5,b=3):
-
$a = 5 + 3 = 8(a变成8,b仍是3) -
$b = 8 - 3 = 5(b变成原来的a值5) -
$a = 8 - 5 = 3(a变成原来的b值3)
示例三:使用乘除运算交换(不借助第三个变量)
乘除法是加减法的变种,原理相同。
<?php
$a = 234;
$b = 345;
// 交换过程(乘除法)
$a = $a * $b; // 第一步:a变成两数之积
$b = $a / $b; // 第二步:b变成原来的a值
$a = $a / $b; // 第三步:a变成原来的b值
echo "a = {$a}<br>";
echo "b = {$b}<br>";
?>
输出:
a = 345
b = 234
本节课程知识要点
| 知识点 | 说明 |
|---|---|
| 临时变量法 | 通用性强,适用于任何数据类型(数字、字符串、数组、对象等) |
| 加减法交换 | 仅适用于数字,但注意整数溢出问题 |
| 乘除法交换 | 仅适用于数字,需额外注意除零和精度问题 |
| 运算顺序 | 算术交换的三步顺序不能调换,否则结果错误 |
| 代码可读性 | 临时变量法更直观,维护成本低 |
三种方法的对比分析
| 维度 | 临时变量法 | 加减法 | 乘除法 |
|---|---|---|---|
| 适用范围 | 任意类型 | 仅数字 | 仅数字 |
| 额外内存 | 需要一个变量 | 不需要 | 不需要 |
| 溢出风险 | 无 | 有(两数之和可能溢出) | 有(乘积可能溢出) |
| 特殊值问题 | 无 | 无 | 除数不能为0 |
| 代码可读性 | 直观 | 需要理解 | 需要理解 |
算术交换法的潜在问题
问题一:整数溢出
当两个数都很大时,$a + $b或$a * $b的结果可能超出PHP整数类型的范围。虽然PHP会自动转为浮点数,但浮点数存在精度问题,可能导致交换后数值出现微小偏差。
$a = 9e18; // 接近整数上限
$b = 9e18;
$a = $a + $b; // 结果超出整数范围,转为浮点数
$b = $a - $b; // 浮点数运算可能不精确
问题二:乘除法的除零问题
如果$b的初始值是0,乘除法交换会失败:
$a = 10; $b = 0;
$a = $a * $b; // a = 0
$b = $a / $b; // 除零错误!程序终止
问题三:处理浮点数时的精度问题
$a = 0.1; $b = 0.2;
$a = $a + $b; // 可能是0.30000000000000004
$b = $a - $b; // 结果可能不是精确的0.1
个人经验与建议
在开发中,我几乎只用临时变量法。理由有几点:
第一,可读性优先。六个月后回头看你写的代码,$temp = $a; $a = $b; $b = $temp这三行不需要任何注释就能理解。算术法虽然节省了一个变量,但需要读代码的人花几秒钟去理解运算过程。
第二,适用性广。临时变量法可以交换字符串、数组、对象,甚至混合类型。而算术法只能处理数字。
第三,没有副作用。不用担心溢出、精度、除零这些问题。
那算术交换法什么时候用?我个人觉得主要是在两种场景:一是算法竞赛或面试中,题目明确要求“不使用额外变量”;二是嵌入式或内存受限的环境下,确实连一个额外的变量都想省掉。在常规的Web开发中,不需要刻意回避临时变量。
扩展:使用list()语法糖交换
PHP中还有一种更简洁的交换写法,利用list()构造语法:
<?php
$a = 45;
$b = 78;
[$a, $b] = [$b, $a]; // 一行完成交换
echo "a = $a, b = $b"; // a = 78, b = 45
?>
这种写法在PHP 7.1以上版本中可用。它实际上在内部创建了一个临时数组,本质上还是借用了额外存储空间,但代码写起来很简洁。我自己在比较新的项目中会倾向于用这种写法。
常见错误与排查
错误1:算术交换时三步顺序写错
-
例如:
$a=$a+$b; $a=$a-$b; $b=$a-$b; -
结果:两个变量最终都变成原始a的值
-
解决:记住三句话——和变差,差变原,和减差变另原
错误2:乘除法交换时遇到0
-
结果:除零错误,脚本终止
-
解决:交换前判断是否有0,或者直接用临时变量法
错误3:临时变量法忘记使用变量
-
例如:
$temp = $a; $a = $b; $temp = $b;(之后一行写错了) -
结果:b的值丢失了
-
解决:第三步是
$b = $temp,不要写反