主题
算术运算符
算术运算符用来对数字做加减乘除、取余和乘方。保存为 math.php 后执行 php math.php:
php
<?php
$a = 10;
$b = 3;
echo $a + $b, "\n"; // 13
echo $a - $b, "\n"; // 7
echo $a * $b, "\n"; // 30
echo $a / $b, "\n"; // 3.333...
echo $a % $b, "\n"; // 1
echo $a ** $b, "\n"; // 1000一览
| 运算符 | 名称 | 例子 | 结果 |
|---|---|---|---|
+ | 加 | 10 + 3 | 13 |
- | 减 / 负号 | 10 - 3、-$n | 7、相反数 |
* | 乘 | 10 * 3 | 30 |
/ | 除 | 10 / 4 | 2.5 |
% | 取余 | 10 % 3 | 1 |
** | 幂 | 2 ** 3 | 8 |
++ | 自增 | 见下文 | 加 1 |
-- | 自减 | 见下文 | 减 1 |
加、减、乘
用法和数学里一样。一元 - 用来取相反数,一元 + 几乎用不到:
php
<?php
$n = 5;
echo -$n, "\n"; // -5
echo 20 - 4 * 2, "\n"; // 12,先乘后减
echo (20 - 4) * 2, "\n"; // 32,括号优先拿不准优先级时加括号,读起来更清楚。
除法 / 和整除
/ 即使两边都是整数,结果也可以是浮点数:
php
<?php
var_dump(7 / 2); // float(3.5)
var_dump(8 / 2); // float(4) 注意:类型是 float只要整数部分时,用 intdiv()(向零取整):
php
<?php
var_dump(intdiv(7, 2)); // int(3)
var_dump(intdiv(-7, 2)); // int(-3)(int) (7 / 2) 也能得到 3,但先做浮点除法再转换,极大的整数可能有精度问题。需要整除时优先 intdiv()。
除以零
PHP 8 里三种除法对「除数为 0」的处理不一样:
php
<?php
var_dump(1 / 0); // Warning,结果 float(INF)
var_dump(1 % 0); // DivisionByZeroError
var_dump(intdiv(1, 0)); // DivisionByZeroError正式代码里除之前先判断除数,不要依赖 Warning 或异常。
取余 %
% 求的是整除后的余数,操作数会先转成整数:
php
<?php
echo 10 % 3, "\n"; // 1
echo 10 % 2, "\n"; // 0,常用来判断偶数
echo 7.9 % 2, "\n"; // 1,7.9 会先变成 7余数的符号跟被除数走:
php
<?php
echo 10 % 3, "\n"; // 1
echo -10 % 3, "\n"; // -1
echo 10 % -3, "\n"; // 1判断奇偶用 $n % 2 === 0,不要写成 $n % 2 == false。
幂 **
$base ** $exp 表示「底数的指数次方」。它是右结合:
php
<?php
echo 2 ** 3, "\n"; // 8
echo 2 ** 3 ** 2, "\n"; // 512,等价于 2 ** (3 ** 2)
echo (2 ** 3) ** 2, "\n"; // 64** 的优先级比一元负号更高,-2 ** 2 其实是 -(2 ** 2),结果是 -4。要算 (-2) ** 2 必须加括号。
自增、自减
++ 让变量加 1,-- 让变量减 1。写在变量前面或后面,返回值不同:
php
<?php
$i = 1;
echo ++$i, "\n"; // 2,先加再取值
echo $i, "\n"; // 2
$j = 1;
echo $j++, "\n"; // 1,先取值再加
echo $j, "\n"; // 2| 写法 | 含义 |
|---|---|
++$i | 先加 1,表达式的值是加完之后的 |
$i++ | 表达式的值是加之前的,然后再加 1 |
--$i / $i-- | 同理,改为减 1 |
只想改变量、不关心返回值时,++$i 和 $i++ 效果相同。不要在同一个表达式里多次改同一个变量(例如 echo $i + $i++),结果依赖求值顺序,难以维护。
字符串自增是 PHP 的特殊规则("Z"++ 会变成 "AA"),初学不要依赖,计数请用整数。
字符串会当成数字吗
PHP 是弱类型,算术运算会尝试把字符串转成数字:
php
<?php
var_dump("10" + 2); // int(12),数字字符串可以算
var_dump("10.5" * 2); // float(21)完全不是数字的字符串,PHP 8 会直接报错:
php
<?php
var_dump("abc" + 2); // TypeError: Unsupported operand types: string + int「前面是数字、后面有杂物」会 Warning,并只用前面的数字:
php
<?php
var_dump("10abc" + 2); // Warning,结果 int(12)拼接字符串请用 .,不要用 +:
php
<?php
echo "第 " . 8 . " 课\n"; // 第 8 课
echo "第 " + 8 + " 课\n"; // 不会得到你以为的句子优先级(先记常用的)
从高到低,大致是:
**- 一元
+/-、++/-- *///%+/-(加减)和字符串.
php
<?php
echo 2 + 3 * 4, "\n"; // 14
echo 2 * 3 ** 2, "\n"; // 18
echo 10 - 4 - 2, "\n"; // 4,减是左结合拿不准就写括号。复合赋值、比较、逻辑运算的优先级见后面几篇。
练习
- 定义
$price = 49、$count = 3,输出总价、以及打 8 折后的价格。 - 用
%判断17是奇数还是偶数,并echo出来。 - 分别输出
7 / 2和intdiv(7, 2),用var_dump看类型差别。 - 写一段代码演示
++$i和$i++输出值的不同。