从零开始学PHP
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

第5章 运算符、表达式和语句

计算机编程发展到现在,不论什么语言都能看出两个特征——英语和数学。从第4章知道了如何用变量表达数据,但还是不知道它是怎么“变”的,本章将会温习小学知识,让程序做加减乘除等运算,以及学习如何用程序表达需要执行的指令,这样将让数据变化起来,让变量成为名符其实的“变”量。

5.1 算数运算符

在现实世界中,不论什么事物,只要变化就涉及运算,比如现实中的建筑工地,随着砖块进行加法运算,楼层就逐渐增高,人们的笑脸随着钱包里的钱进行加法运算,忧愁就相应减少,笑容就越灿烂。首先,从加减乘除运算开始。

5.1.1 加减乘除

PHP中的加减乘除和生活中的加减乘除一样,非常好理解,如下列代码。

        <?php
        $a = 5 + 3 – 2 * 6 / 4;
        >

乘法和除法的符号和小学课本上学到的有点不一样,以上代码中的变量$a最后得到的值是5。程序首先计算2乘以6,然后除以4,得到3,再然后是5加3减3,等于5。

除号(“/”)总是返回浮点数,即使两个运算数是整数(或由字符串转换成的整数也是这样)。

5.1.2 求模

除了加减乘除(+,-,*,/)以外,求模(%)操作也是PHP常用的操作符,求模也叫求余数,并不是进行“百分比”的运算。以下是求余数操作的例子。

        <?php
        $a = 5 % 2;
        ?>

以上代码中的变量$a的结果是1,意思是5除以2,余数为1。

注意 取模$a % $b在$a为负值时,结果也是负值。

5.1.3 取反

数字取反操作。

        <?php
        $a = 5;
        $b = -$a;
        ?>

以上代码中变量$b的结果为-5。如果$a是字符串,运算结果将会是0。

5.2 赋值运算符

在前面的章节中,几乎都能看到和以下代码类似的代码。

        <?php
        $a = 5;
        ?>

这条语句定义了变量$a,其中的“=”不是现实中“等于”的意思,在这之前很多人可能都会把这个“=”符号认为是“等于”。在PHP中,“=”是赋值运算符,意思是把右边的值赋给左边的变量。

5.3 自运算符

自运算符,按其字面意义可以理解为自己运算符。下面看一个常见的例子。

        01   <?php
        02
        03   $a = 5;
        04   $a = $a + 1;
        05   ?>

通过上节知道,第3行的意思是把数字5赋值给变量$a。想象程序在往下一行执行,第4行的意思是先计算出 $a + 1的值,然后将该值赋给$a,最终$a的值在原来的值(5)基础上加了1,现在$a的值为6。这就好比动物园里本来有$a(5)条狗,现在又生了1个,那么用PHP表达就是$a = $a + 1。不过通常情况下都不这样写代码,因为有运行效率更好的写法,请看如下代码。

        <?php
        $a = 5
        $a += 1;
        ?>

运算符“+=”是一个操作符,因此符号“+”和“=”要连在一起,中间不能有空格,其实现的操作是,在自身(运算符“+=”左边的值)基础上,加上右边的值。上例代码中变量$a的值最后是6。

不光是加法,同样的,减、乘、除、求余也有这种操作符“-=” 、“*=”、“/=” 、“%=”,下面是一些例子,运行这些例子时,假设变量$a的值都是5。

        <?php
        $a -= 2; // 执行后$a的值是3
        $a *= 2; // 执行后$a的值是10
        $a /= 2; // 执行后$a的值是2.5
        $a %= 2; // 执行后$a的值是1
        ?>

PHP提供这些操作符,目的仅仅是为了提高相应操作的运算速度。在某些特殊情况下,优化还可以继续,请看下一小节。

5.4 递增/递减运算符

当运算是自加或自减1的时候,PHP提供了更为优化的运算操作符“++”和“--”。假设整型变量a的值为10,从上面小节的内容已经知道,要实现对其加1,可以有以下两种写法。

        <?php
        $a = 10;
        // 方法1
        $a = $a +1;
        // 方法2
        $a += 1;
        ?>

其中方法2比方法1好。现在还有方法3,并且是最好的方法。

        <?php
        $a = 10;
        // 方法3
        ++$a;
        // 或者
        $a++;
        ?>

在只是自加1的情况下,代码$a++或++$a可以运行得更快。同样,自减1操作也有对应的操作符,如--$a或$a--。

现在来谈谈++$a和$a++有什么区别。在PHP语言中,++$a和--$a被称为前置运算(prefix),而$a++和$a--称为后置运算(postfix),如果仅仅是进行前置运算或后置运算,那么结果是相同的,这已经在前面提过,以++为例,假设将变量$a的值设为10,则无论是++$a或是$a++,执行结果都是让$a递增1,结果为11。但是,在有其他运算的复杂表达式中,前置++运算过程是先加1,然后将已经加1的变量参与其他运算,而后置++的运算过程是先用未加1的变量参与其他运算,然后再将该变量加1。

以上听起来有些绕,举些例子看,还是将变量$a的值设为10。

【例子1】

        <?php
        $a = 10;
        $b = ++$a; // 前置++
        ?>

运算结果是变量$a的值为11,$b的值也为11。

代码分析:代码第4行先计算++$a,结果$a的值为11,然后再计算$b = $a,结果变量$b的值也为11。

【例子2】

        <?php
        $a = 10;
        $b = $a++; // 后置++
        ?>

运算结果是变量$a的值为11,但$b的值却是10。

代码分析:代码第4行先计算$b = $a,因此,$b的值是未加1之前的$a,所以为10,然后再计算$a++,$a的值为11。

再举一个复杂点的表达式例子。

        <?php
        $a = 10;
        $c = 5;
        $b = $a++ + $c;
        ?>

执行这些代码,$b的值为15。倘若换成前置运算。

        <?php
        $a = 10;
        $c = 5;
        $b = ++$a + $c;
        ?>

执行这些代码,$b值为16。想一想,为什么?然后自己手动用“--”运算符操作一次,看看最后结果是多少。

“++”运算符和“--”运算符能加快运算速度,但在运算上有以上例子中的小区别,很容易让程序员的代码变得不清晰,造成代码的运行结果不一样,所以在写代码时,尽量不要依赖于前置和后置运算,应该尽量避免(尽管使用前置和后置运算会使这些代码看上去酷酷的,像“高手”所写)。

5.5 字符串运算符

在PHP中有两个字符串运算符。

第一个是连接运算符(“.”),返回其左右参数连接后的字符串。

第二个是连接赋值运算符(“.=”),将其右边参数附加到左边的参数后。

        <?php
        // 连接运算符
        $a = "Hello ";
        $b = $a . "World!";
        // 连接赋值运算符
        $a = "Hello ";
        $a .= "World!";
        ?>

5.6 比较运算符

算术运算所得的结果是数值。而比较运算符,如同名称所表示的,它允许对两个值进行比较,所得的结果为逻辑值,也称布尔值,即前面章节中提到的布尔类型允许的值:真或假。真用true表示,假用false表示。

用一句话说,比较运算符就是将比较运算符两边的值进行比较,如果两边的值相同,返回布尔值“TRUE”(真),如果不相同,返回布尔值“FALSE”(假)。以下演示列出了所有比较运算符。

        <?php
        // 如果 $a 等于 $b,运算结果为TRUE
        $a == $b;
        // 如果 $a 等于 $b,并且类型也相同,运算结果为TRUE
        $a === $b;
        // 如果$a不等于$b,运算结果为TRUE
        $a != $b;
        // 如果$a不等于$b,运算结果为TRUE
        $a <> $b;
        // 如果 $a 不等于 $b,或者它们的类型不同,运算结果为TRUE
        $a !== $b;
        // 如果$a小于$b,运算结果为TRUE
        $a < $b;
        // 如果$a大于$b,运算结果为TRUE
        $a > $b;
        // 如果$a小于或等于$b,运算结果为TRUE
        $a <= $b;
        // 如果$a大于或等于$b,运算结果为TRUE
        $a >= $b;
        ?>

5.7 逻辑运算符

逻辑运算有以下4个操作符。

● ! (非,取逻辑反,NOT)。

● &&(逻辑与,并且,AND)。

● || (逻辑或,或者,OR)。

● Xor (逻辑异或)。

以下是代码实例。

        <?php
        // And(逻辑与)
        $a and $b;
        // Or(逻辑或)
        $a or $b;
        // Xor(逻辑异或)
        $a xor $b;
        // Not(逻辑非)
        ! $a;
        // And(逻辑与)
        $a && $b;
        // Or(逻辑或)
        $a || $b;
        ?>

在代码中可以看出,运算符&&(与)和||(或)有两种表示法,这是因为在PHP中,这两个不同的运算符优先级不一样,符号&&和||高于文字and和or。运算符优先级类似于乘法、除法的优先级大于加法或减法。下面是现实世界的逻辑描述对应于PHP中的逻辑描述。

● 在现实世界中,只有条件A和条件B都成立时……这样的表达,用PHP描述则是A &&B。

● 在现实世界中,只要条件A或者条件B成立任意一个时……这样的表达,用PHP描述则是A || B。

● 在现实世界中,只要条件A或者条件B成立任意一个,但不同时成立时……这样的表达,用PHP描述则是A xor B。

5.8 位运算符

位运算符允许对整型数中指定的位进行置位。如果左右参数都是字符串,则位运算符将操作字符的ASCII值。

● $a & $b,And(按位与)将把$a和$b中都为1的位设为1。

● $a | $b,Or(按位或)将把$a或者$b中为1的位设为1。

● $a ^ $b,Xor(按位异或)将把$a和$b中不同的位设为1。

● ~ $a,Not(按位非)将 $a中为0的位设为1,反之亦然。

● $a << $b,将$a中的位向左移动$b次(每一次移动都表示“乘以2”)。

● $a >> $b,将$a中的位向右移动$b次(每一次移动都表示“除以2”)。

注意 在32位系统上不要右移超过32位。不要在结果可能超过32位的情况下左移。

5.9 执行运算符

PHP支持一个执行运算符反引号(``)。这不是单引号(普通PC键盘上,大键盘数字区域最前面一个标有波浪号“~”和反引号“`”的键),PHP尝试将执行运算符(反引号)中的内容作为外壳命令来执行,并将其输出信息返回(例如,可以赋给一个变量而不是简单地丢到标准输出)。这个通常用来执行操作系统命令。

5.10 错误控制运算符

PHP支持一个错误控制运算符“@”。当“@”放置在一个PHP表达式之前,该表达式可能产生的任何错误信息都被忽略掉。如果激活了track_errors特性,表达式所产生的任何错误信息都被存放在变量 $php_errormsg中。此变量在每次出错时都会被覆盖,所以如果想要及时知道出错信息,就要尽早检查$php_errormsg变量的值。

警告 目前的“@”错误控制运算符前缀甚至使导致脚本终止的严重错误的错误报告也失效。这意味着如果在某个不存在或类型错误的函数调用前用了“@”来抑制错误信息,那脚本会没有任何迹象显示原因而死在那里。

注意 “@”运算符只对表达式有效。例如,可以放在变量、函数和include()调用、常量等之前。但不能放在函数或类的定义前,也不能用于条件结构前。

错误控制符通常用于忽略脚本中可有可无的错误信息,比如打开某些网站的时候,就发现页面顶部打印出一些莫名其妙的脚本警告信息,实质上这些错误不影响脚本运行,但有了这些警告信息会影响页面美观度,这时就该用错误控制符了。

5.11 表达式和语句

变量、常量、各种运算符等组成了表达式,表达式用于表达一个计算过程。表达式是PHP最重要的基础,在PHP中,几乎所写的任何东西都是一个表达式。用一句最简单最精确的话来定义表达式就是“表达式是任何有值的东西”。

5.11.1 表达式

最基本的表达式形式是常量和变量。当输入“$a = 5”,即将值“5”分配给变量 $a,而“5”很明显是指其值为5,换句话说“5”是一个值为5的表达式(在这里,“5”是一个整型常量)。赋值之后,所期待的情况是$a的值为5,如果写下“$b = $a”,期望的是$b的值为5,换句话说,$a是一个值,但同时也是5的表达式。

PHP和其他语言一样在表达式的道路上发展,但它推进得更深远。PHP是一种面向表达式的语言,从这一方面来讲几乎一切都是表达式。考虑刚才已经研究过的例子“$a = 5”,很显然这里涉及两个值,整型常量5的值及变量$a的值,但是事实上,这里还涉及另外一个值,即附值语句本身的值,赋值语句本身求值就是被赋的值,即5,实际上这意味着“$a = 5”。

总而言之,以上例子也就是说只要知道是一个值为5的表达式即可。因而,写“$b = ($a = 5)”和写“$a =5; $b=5”(分号标志着语句的结束)是一样的。因为赋值操作的顺序是由右到左的,所以也可以写“$b = $a =5”。

最后举一个复杂的表达式例子。稍微复杂的表达式例子就是函数或类。

        <?php
        function foo ()
        {
            return 5;
        }
        ?>

5.11.2 语句

在PHP中,表达式和语句没有严格的区分,一个表达式加上一个分号,就形成了一个语句,当然也可以单独用一个分号,只是这样的语句是没有意义的,如下面的代码。

        <?php
        5 + 6;
        ?>

对于上面的语句,虽然计算机可以执行该语句,但不改变程序运行逻辑,就像一个人说了句废话,所以这样的语句不能算真正的“语句”。通常所说的语句是指一些表达式组合,能够完成一件事情,才叫语句。例如下面的代码。

        <?php
        $a = 5 + 6;
        ?>

以上代码就是一个有意义语句,因为程序将5加6的值赋给了变量$a,结合上节说到的赋值运算符,这一个表达式就叫赋值语句。

5.12 注释

小明记性不好,总是忘了帮妈妈取报纸,于是小明的妈妈就在门上贴了一张小纸条,提醒小明每天都要取报纸。类似于小明妈妈贴的这张有提醒作用的小纸条,PHP中有起提醒、说明作用的描述方式——注释。在PHP中,注释有以下3种。

        <?php
        // 以双斜线开头的单行注释
        # 以井号开头的单行注释
        /* 以一个斜线和一个星号开始的多行注释
        多行注释以一个星号和一个斜线结束,中间不可以嵌套
        */
        ?>

在编写程序时,最好在需要提醒的地方加一个注释,这是一个好习惯,否则一些晦涩难懂的算法、逻辑就没人看得懂了。注释并不会减慢程序的运行速度。

5.13 小结

学到本章才算是真正跨进了PHP的门,因为有了计算才能算是程序,本章学了在PHP中的加减乘除运算,也第一次接触了赋值运算,还有变化莫测的逻辑运算。从用变量、常量表达数据到变量通过运算真正成为“变量”,这些构成了程序运行的基础。

5.14 习题

一、填空题

1.运算符种类很多,主要有__________、__________、__________、__________等。

2.PHP的位运算符主要有_____、_____、______、______、______和________。

二、选择题

1.赋值运算符“%=”的意义是( )。

A.将左边的值对右边取余数赋给左边

B.将左边的值除以右边的值赋给左边

C.将右边的值对左边取余数赋给左边

D.将右边的值除以左边的值赋给左边

2.逻辑运算符“Xor”的意义是( )。

A.$a和$b不同时为真,则结果为假

B.$a和$b同时为真,则结果为真

C.$a和$b不同时为真,则结果为真

D.以上都不对

3.下面程序的运行结果是( )。

        <?php
          $a=1;
          $a++;
          $c=&$a;
          $b=$c++;
          echo "\$a=$a <br> \$b=$b <br> \$c=$c ";
        ?>

A.$a=3 $b=2 $c=3

B.$a=3 $b=2 $c=2

C.$a=2 $b=2 $c=3

D.$a=2 $b=2 $c=2