PHP 运算符
之前学的是“变量”、“常量”,他们都是“量”。
量是干什么的呢?
说白了,“量”是为了参与计算的。
光要“量”意义是不大的,量还要参与运算才行。
量与量之间有那些运算的方式?
就是下面所要学的运算符的概念。
本篇要学是两个概念:
第一个是"运算符的概念"
第二个是"表达式的概念"
先看运算符
一、算数运算符
PHP程序如何进行加、减、乘、除、取模的运算依次是+, -, *, /, %
$a = 3; $b = 5; /** * 加: * "$c = $a + $b" 这条语句的含义是"$a + $b"的计算结果,然后赋给$c * 此处"等于号"是赋值的意思,不是数学上的等于号(数学上的等于号是相等的意思) * 把a + $b的值赋给$c,然后打印$c,输出数字 8 */ $c = $a + $b; echo $c,'<br/>'; // 8 /** * 减: * $b - $a * 计算"$b - $a"的值,计算结果echo出来 2 */ echo $b - $a,'<br/>'; // 2 /** * 乘: * $a * $b * 计算$a * $b的结果,然后赋给$c */ $c = $a * $b; echo $c,'<br/>'; // 15 /** * 除: * $b / $a * 1. "5 / 3" 如果严格在数学上,是小数点6后面的6无限循环, * 2. 但计算机里存储是有限的不可能无限循环,所以最后就约数1.6666666666667 */ $c = $b / $a; echo $c; // 1.6666666666667 /** * 提示: * 如果是在C语言中$b、$a都是整型,他俩的计算结果$c,还是整形 * * 在PHP中,变量的值可以随时的改变值和类型,也可以重新赋值。 * 比如: 变量$c是整型,可以突然赋一个浮点型值,非常的灵活,因此PHP被称为动态语言 * */
求余,专业叫"取模运算"
$a = 3; $b = 5; /** * 小学算术 "5 / 3 = 得1余2" * 其实在计算机里面,计算除法的时候,就是算出两个结果,商 和 余数(学过汇编) * 用百分号来取模求余 * $b % $a 求余数(取模)是 2 * */ $c = $b % $a; echo $c; // 2
小测试,判断一个数是偶数,还是奇数?
/** * 奇数: 1, 3, 5, 7... * 偶数: 2, 4, 6, 8... * * 判断一个数,是偶数,还是基数? * 可以对2取模,如果余数是1是奇数,如果余数是0是偶数 * */ $d = 1; $res = $d % 2; if($res == 1){ echo $d,' 是奇数<br/>'; // 输出: 1 是奇数 }else if($res == 0){ echo $d,' 被2整除了,是偶数<br/>'; } /* ++++++++++++++++++++++++++++++++++++++++ */ $d = 2; $res = $d % 2; if($res == 1){ echo $d,' 是奇数<br/>'; }else if($res == 0){ echo $d,' 被2整除了,是偶数<br/>'; // 输出: 2 被2整除了,是偶数 } /* ++++++++++++++++++++++++++++++++++++++++ */ $d = 3; $res = $d % 2; if($res == 1){ echo $d,' 是奇数<br/>'; // 输出: 3 是奇数 }else if($res == 0){ echo $d,' 被2整除了,是偶数<br/>'; } /* ++++++++++++++++++++++++++++++++++++++++ */ $d = 4; $res = $d % 2; if($res == 1){ echo $d,' 是奇数<br/>'; }else if($res == 0){ echo $d,' 被2整除了,是偶数<br/>'; // 输出: 4 被2整除了,是偶数 }
上面是小学的数学比较简单
初中数学有了"负整数"的概念,当被除数是负数的时候,取模怎么来理解?
$b = -5; $a = 3; echo $b % $a,'<br/>'; // 负数-5对正数3取模,结果是 -2 $b = -5; $a = -3; echo $b % $a,'<br/>'; // 负数-5对负数-3取模,结果还是 -2
记住这句话:在取模运算的时候,余数的符号和被除数的符号是一致。
被除数是正数5,取模结果是整数 2
$b = 5; $a = -3; echo $b % $a; // 2
注意两个点:
PHP中两个整数相除,结果有可能是浮点型
取模运算结果的符号和被除数保持一致
二、比较运算符
罗列一下比较运算符:
> 大于
< 小于
>= 大于等于
<= 小于等于
== 等于
!= 不等于
=== 全等于(不仅值相等,变量的类型也相等)
!== 不全等于
1、大于,小于,大于等于,小于等于
$a = 3; $b = 2; /** * $a > $b * 3 > 2 * 输出: 3果然大于2 * */ if($a > $b){ echo $a,'果然大于',$b,'<br>'; // 输出: "3果然大于2 }else{ echo $a,'并不大于',$b,'<br>'; } /** * $a >= $b * 3 >= 2 * 意味着:3比2大,或者3等于2,都可以 * 输出: 3并不大于等于2 * */ if(3 >= 2){ echo $a,'果然大于等于',$b,'<br>'; // 3果然大于等于2 }else{ echo $a,'并不大于等于',$b,'<br>'; } /** * $b的值修改为 3 * $a >= $b * 3 >= 3 * 意味着:3比3大,或者3等于3,都可以 * 输出: 3并不大于等于2 * */ $b = 3; // $b的值修改为 3 if($a >= $b){ echo $a,'果然大于等于',$b,'<br>'; // 输出"3果然大于等于3" }else{ echo $a,'并不大于等于',$b,'<br>'; } /** * < 小于 * <= 小于等于 * 小于和小于等于同上 * */
等于和全等于容易搞混,所以下面先看“全等于”
2、全等于(===)
$a = 3; // 整型3 $b = 3; // 整型3 /** * $a === $b * 3 === 3 * 输出: "3等于3" * */ if($a === $b){ echo $a,'等于',$b,'<br/>'; // 输出: "3等于3" }else{ echo $a,'不等于',$b,'<br/>'; } /** * $a改成2 * $a === $b * 2 === 3 * 输出: "2不等于3" * */ $a = 2; // 整型2 if($a === $b){ echo $a,'等于',$b,'<br/>'; }else{ echo $a,'不等于',$b,'<br/>'; // 输出: "2不等于3" }
整型 和 整型比没有什么问题
下面整型 和 字符串的比较
$a = 2; // 整型2 $b = '3q'; // 字符串'3q' /** * $a === $b * 2 === '3q' * 输出: 2不等于3q * */ if($a === $b){ echo $a,'等于',$b,'<br/>'; }else{ echo $a,'不等于',$b,'<br/>'; // 输出:2不等于3q } /** * $a改成3 * $a === $b * 3 === '3q' * 输出:3不等于3q * */ $a = 3; // 2改成3(还是整形) $b = '3q'; // 字符串'3q' if($a === $b){ echo $a,'等于',$b,'<br/>'; }else{ echo $a,'不等于',$b,'<br/>'; // 输出:3不等于3q }
整形3 和 整形3相等,理所当然
整型3 和 字符串'3q'不相等,也理所当然的
接下来有意思了:
还是整型3 和 字符串'3q',换两个等号的
3、等于(==)
$a = 3; // 整型3 $b = '3q'; // 字符串'3q' /** * 换成等号(==) * 3 == '3q' * 输出:3等于3q * */ if($a == $b){ echo $a,'等于',$b; // 输出:3等于3q }else{ echo $a,'不等于',$b; }
整数3怎么会等于字符串"3q"呢?
=== 是全等于,必须变量类型相等,并且变量值相等,然后才等于,也就是说判断的非常严格
== 只是等于,并不要求变量类型必须相等
但是如果类型都不一致,两者又谈何相等,整型3怎么会等于字符串'3q'呢?
下面再来做一个判断
$a = true; // 布尔类型 true $b = 5; // 整数型 5 if($a == $b){ echo 'true等于5'; // 输出:true等于5 }else{ echo 'true不等于5'; }
true是布尔类型(布尔类型只有true/false两种情况),true 和 整型5根本就不是一个数据类型,是怎么比较的呢?
再不同的类型的比较时,PHP程序会把变量转换成一致的类型,然后再去比较。
三、转换类型
着重记以下几个转换:
1. 布尔值 --> 字符串
2. 字符串 --> 数字
3. 字符串 --> 布尔
4. 数字 --> 布尔
5. 数字 --> 字符串
1、数字转布尔(4. 数字 --> 布尔)
上面以 整型5 和 true 的比较为例,PHP把整型5转换成布尔型,那么整型5转成布尔值之后是true。
其实有的语言中,根本就没有布尔值类型,都是用1、0充当true/false
只有 0 和 0.0 这两个值转换成布尔是false,其它转化成布尔值都是true,包括负数转换布尔型也是true
/** * 0.0 == true * 1. 0.0转换成布尔值是false,整数0转成布尔值也是false * 只有整型的0、和浮点数0.0转成false,其它甚至负数都转成true * 2. false == true * 3. 输出:0.0 != true * */ if(0.0 == true){ echo '0.0 == true'; }else{ echo '0.0 != true'; // 输出:0.0 != true }
只有整型的0、和浮点数0.0转成false,其它甚至负数都转成true
if(-3 == true){ echo '-3 == true'; // 输出:-3 == true }else{ echo '-3 != true'; }
这是好多人都容易误会的一点,负数转换布尔值也是true
也就是说,只有0、 0.0包括0.0000这种转布尔型是false,其它的都是true,包括负数也是true
2、布尔值转字符串(1. 布尔值 --> 字符串)
1). true --> '1' (true转换成字符串1 )
2). false --> '' (fasle转成空字符串 )
3、字符串转数字(2. 字符串 --> 数字)
规律,从字符串左端开始找数字,直到第一个非数字结束,取出来的这一部分,是转化后的值
根据这个规律,字符串'3q' 和 整型3 比较的时候,'3q'被转化成整型,'3q'是怎么被转换成整型?
从左到右找直到第一个不是数字的,'3q'从左到右找只找到一个3,因此3被转化成整型3
'3q' ==> 转成整形是3
'123abc456' ==> 转成整形是123
'fdsafdsaf789' ==> 转成整形是0
从左到右找'fdsafdsaf789' ,刚找一下碰第一个非0就立即结束查找(刚找一下就碰到字母"f",就立即结束了),立即结束什么都没找到,因此转成整型是0
/** * 'fdsafdsaf789'转换成0 * 0 + 0 等于 0 * */ $num = 'fdsafdsaf789'; echo $num + 0; // 0
4、字符串转布尔型( 3. 字符串 --> 布尔)
字符串 到 布尔型的转换非常的好记,就是 空字符串''、空字符串里只有一个'0',这两种转换成false,其它的一概是true
/** * 空字符串转布尔是false,'0'转成false,其它的全部是true * * '' == false * 1. 空字符串转布尔是false * 2. 反过来看false转成字符串也是空字符串'',false当然等于false,因此判断为真 * 3. 输出:空字符串等于false * */ if('' == false){ echo '空字符串等于false <br/>'; // 空字符串等于false }else{ echo '空字符串不等于false <br/>'; } /** * '0' == false * 1. 空字符串里面加一个'0' * 2. '0'也等于false * 3. 输出:字符串'0'等于false * */ if('0' == false){ echo "字符串'0'等于false <br/>"; // 字符串'0'等于false }else{ echo "字符串'0'不等于false <br/>"; } // 字符串就这两种情况是false,其它的一概是true
PHP手册 -> 语言参考 -> 类型 -> 类型转换的判断
没必要一个一个来记手册,常见的就是上面这几种,布尔转字符串,字符串转数字……
5、专门记住这两个特例
1). 字符串转布尔,就 '' 空字符串、字符串'0' 这两种情况是false,其它的情况都是true
2). 整形只有0、0.0是false,其它的一概是true
比如,字符串'0'非要改成'0.0',就不等于false了
if('0.0' == false){ echo "字符串'0.0'等于false"; }else{ echo "字符串'0.0'不等于false"; // 字符串'0.0'不等于false }
所以就严格的按照上面两个特例的规律来
6、数字转字符串(5. 数字 --> 字符串)
数字 转 字符串是最简单的,直接就是字面本身
echo 'abc' . 123; // 输出字符串类型的:'abc123'
比较运算符中间还牵扯到了类型转换
为什么 3 == '3q'
为什么 5 == true
就是因为用到了类型转换的机制在发挥作用
四、字符串运算符
"数字"都能计算、比较,"字符串"能有某种运算吗?
在PHP中“字符串”有一种运算就是“拼接”,运算符是“.”点
$str1 = 'hello'; $str2 = ' '; $str3 = 'world'; $str = $str1 . $str2 . $str3; echo $str; // hello world
字符串运算就这一个点运算符,但是新手的疑问,甚至工作半年左右了还疑问,怎么可以用逗号?
$str1 = 'hello'; $str2 = ' '; $str3 = 'world'; echo $str1, $str2, $str3, '<br/>'; // hello world echo $str1 . $str2 . $str3.'<br/>'; // hello world /** * 新手的疑问,怎么可以用逗号? * * echo $str1 . $str2 . $str3.'<br/> 这行是在内存中拼接运算, * 运算出一个'hello world <br/>'这样的大字符串,然后echo输出,自然看到我们看到的结果。 * * echo $str1, $str2, $str3, '<br/>' * 因为echo是一个语句,负责输出用的,然后echo的输出可以通过","逗号分隔,一次性输出多个变量或值来。 * * 综上: * 用'.'(点)是先拼接,再整个输出 * 用','(逗号)是挨个的把3个变量输出 * * 面试的时,会碰到这样的问法:上面的两种情况,用点"." 和 用逗号","那个输出的快、效率高? * 答: ','逗号快,因为省去了一次"拼接计算"的过程。 * */
五、赋值运算符
赋值运算符就是等号(=),他的作用是把等号右边的值,赋给左边的变量。
$a = 3; // 把3赋给变量$a
还可以连着写
$b = $c = $d = 5; echo $b,$c,$d; // 555 /** * $b = $c = $d = 5; 从右向左都赋上了5 * * 赋值运算符连着写如何发挥的作用? * 1. 先把5赋给$d,然后$d的值此时已经等于5了 * 2. 再把这个5赋给$c,此时$c的值也已经等于5了 * 3. 再把值5赋给$b * */
六、运算符的运算结果
既然是运算,运算完毕之后,必须得有一个结果 —— 结果值
1、"算数运算符"的运算结果
3 + 2; 运算结果是 5,很容易理解
/** * $c = $a + $b * $a和$b他俩相加运算结果是 5 * var_dump($c);返回Int类型的 int(5) * */ $a = 3; $b = 2; $c = $a + $b; echo $c, '<br/>'; // 5 var_dump($c); // int(5)
2、"比较运算符"的运算结果
3 == 2; 这个运算结果是多少?
既然是运算,最终肯定的产生一个结果出来,问题是比较运算的结果是什么呢?
注意,比较运算符返回结果,只有两个可能,true / false
以 3 ==2 为例子,要么等于,要么不等于(要么是真,要么是假)
3不等于2因此运算结果是false
/** * 3 == 2; 比较运算结果是什么? * 1. 如果拿不准用小括号把(3 == 2)包起来,这两个整合在一起发挥作用,其实3 == 2不加小括号也行 * 2. 然后var_dump($c)返回:bool(false) * 所以说比较运算符,要么返回真,要么返回假 * */ $c = (3 == 2); var_dump($c); // bool(false)
再看 $d = 3 > 2
/** * $d = 3 > 2; * 1. 3 > 2,3和2他俩运算,返回的值是真 * 2. 返回的值true,赋给了$b * 3. var_dump($c)返回bool(true) * */ $d = 3 > 2; var_dump($d); // bool(true)
所以说比较运算符很简单,要么返回真,要么返回假
3、"字符串运算符"返回的运算结果
字符串运算符(太简单了)返回结果,返回拼接后的的字符串。
$a = 'Hello'; $b = 'World'; echo $a . $b; // HelloWorld
4、"赋值运算符"的返回结果
赋值运算符,返回值是多少呢?
$a = 3;
最让我们疑惑的是赋值运算符,赋值运算符一定是有返回值的。
看下面这个情景
/** * if($a = 99) * 知道不知道,if里判断的是那个值? * 1. 等于号(=)也是一种运算,运算必有结果 * 2. 赋值运算符的运算结果,就是等号(=)右边的值 * */ if($a = 99){ echo 'aa'; // 输出: aa }else{ echo 'bb'; } /** * $b = $a = 99; * 1. $a = 99 的运算结果赋给$b * 2. var_dump($b)输出 int(99) * */ echo '<br>'; $b = $a = 99; var_dump($b); // int(99)
回头再来看看刚才那道题,再思考发生了什么?
/** * 再思考一下,发生什么 * $a = $b = $c = $d = 88; * 为什么变量$a, $b, $c, $d都是88 ? * * 过程是这样的: * 1. $d = 88先进行,赋值后返回88 * 2. $d返回的88,再赋值给$c * 3. 同理…… * 4. 最终$a也赋值成了88 * */ $a = $b = $c = $d = 88;
总结
1.算数运算符
2.比较运算符
3. 类型转换
4.字符串运算符(“.”点拼接运算)
5.赋值运算符(“=”等号)
6.运算符运算完毕后的结果
1、注意两个点:
1). 比较运算符时,有一个类型转换的问题
2). 凡是运算必有返回值
- 比较运算,返回布尔值
- 赋值运算,返回赋的值本身
2、再来看这个操作,怎么理解?
$a = 10; $a = $a + 2; /** * $a = $a + 2 经历了两个步骤: * 1. $a原始的值 和 数字2进行算数运算相加 * 2. 既然相加,必然返回计算结果,加2后的新结果,再次赋给$a * 因此打印$a输出12 * */ echo $a; // 12
$a = 2 变量$a的值是10
$a = $a + 2 发生了什么?
CPU运算的是把a的值10加上2,得到一个12
得到12在写入到$a指向的空间里面来,所以$a指向空间的值就变成了12
$a的值就更新成12
3、作业:
一段PHP代码,写出输出结果
考的是赋值运算符和逻辑运算符,以及逻辑运算符的短路特性
$a = 0; $b = 0; if(($a=3)>0 || ($b=3)>0){ $a++; $b++; echo $a; // 4 echo $b; // 1 } /** * $a = 0; * * $b = 0; * * if(($a=3)>0 || ($b=3)>0){ * * echo $a; // 3 * echo '<br/>'; * echo $b; // 0 * * echo '<br/>'; * * $a++; * $b++; * * echo $a; // 4 * * echo '<br/>'; * * echo $b; // 1 * * } * */
七、逻辑运算符
逻辑运算符有这么几种:
逻辑或: || or
逻辑与: && and
异或运算: xor (运算符两边必须不一样)
1、逻辑或
看几个生活中的问题,用生活中的例子来理解逻辑运算符
|| 逻辑或
/** * 一个女生对一个男生说: * 你有住房,或者,有宝马车,就嫁给他 * 前面是条件,后面是根据条件判断的结果 * * 条件有2个:有房 || 有车(条件是或者的关系:或者有房,或者有车) * * 问,此男生 * 有房,既,第一个条件,为真 * 无车,既,第二个条件,为假 * 女生能否嫁给这个男生? * 可以嫁,因为有房或者有车,二个条件满足一个,就可以嫁 * * 问,此男生 * 既有房,又有车,能不能嫁 * 女生,能嫁,还要把闺蜜也带上 * */ $house = 180; // 有180平米大房 $car = ''; // 没有车 if($house || $car){ echo '可以嫁<br/>'; // 输出: 可以嫁 }else{ echo '再等两年<br/>'; } /** * 继续 * 这次男生: * 无房,第一个条件,为假 * 有车,第二个条件,为真 * * 这次女生能否嫁给这个男生? * 输出: 还是可以嫁 * */ $house = 0; // 没有房子 $car = 'BMW'; // 有BMW车 if($house || $car){ echo '还是可以嫁<br/>'; // 输出: 还是可以嫁 }else{ echo '再等两年<br/>'; } /** * 再换一下 * 这次男生: * 无房,第一个条件,为假 * 无车,第二个条件,为假 * * 女生能否嫁给这个男生? * 输出: 再等两年 * */ $house = 0; // 没有房子 $car = ''; // 也没有车 if($house || $car){ echo '也可以嫁<br/>'; }else{ echo '再等两年<br/>'; // 输出: 再等两年 }
2、逻辑且
&& 逻辑且,条件是"并且"的关系
/** * 上面那个女生好说话些,这次碰到女生2号 * * 这次的女2号,对男2号说: * 你必须有住房,并且,还得有宝马车 才能嫁给男2号 * 前面是条件,后面是根据条件判断的结果 * */ $house = 180; // 有房子 $car = ''; // 没有车 $res = $house && $car; // 把"$house && $car"的逻辑运算判断运算结果赋给$res var_dump($res); // bool(false) /** * 男二号: * 有房,第一个条件,为真 * 无车,第二个条件,为假 * 两个条件,没有达到女2号的要求,为假 * * $res = $house && $car; * 1. 把"$house && $car"的逻辑运算判断运算结果,赋给$res * 2. 逻辑运算要么为真,要么为假,所以逻辑运算的结果,就是布尔值 * 3. var_dump($res); 输出:bool(false) * * 所以明确的看到,$res是false * if判断结果,再等两年 * */ echo '<br/>'; if($res){ echo '也可以嫁<br/>'; }else{ echo '再等两年<br/>'; // 输出: 再等两年 }
等两年的过程中,男生去奋斗。
奋斗两年后,房子有了,车也买了,买的是比亚迪车(BYD)。女2号非常严格她就要宝马(BMW)
怎么写"辑判断表达式"?
$house = 180; // 有房子 $car = 'BYD'; // 有比亚迪车 $res = $house && $car == 'BMW';
此处$house && $car == 'BMW',牵扯到运算优先级的问题:
是先做$house && $car逻辑运算,然后$house && $car 再和 'BMW'做全等比较的判断?
还是$car == 'BMW'先比较,比较的结果再和$house做逻辑上并且运算呢?
在多个量进行运算的时候,需要先运算的单元用括号()包起来,这程序易读易理解,不容易产生歧义。
为了确保'BMW'先赋值给$car,加一个小括号包起来 $house && ($car == 'BMW')
/** * $res = $house && ($car == 'BMW'); * 1. ($car == 'BMW')$car先和和宝马比,不相等,因此返回False * 2. $house为真 * 3. 真 并且 假,得到的结果还是假 * 女2号非得要宝马,因此输出:再等两年 * */ $house = 180; // 有房子 $car = 'BYD'; // 有比亚迪车 $res = $house && ($car == 'BMW'); var_dump($res); // bool(false) echo '<br/>'; if($res){ echo '也可以嫁'; }else{ echo '再等两年'; // 输出: 再等两年 }
再奋斗两年后
男生换了宾利车,宾利车比房子加宝马还贵
$house = 180; // 有房子 $car = '宾利'; // 有宾利车 if($house && ($car == 'BMW')){ echo '也可以嫁'; }else{ echo '再等两年(看走眼了...)'; // 输出: 再等两年(看走眼了...) }
3、总结八种结果:
真 或(||) 真 == 真
真 或(||) 假 == 真
假 或(||) 真 == 真
假 或(||) 假 == 假
真 且(&&) 真 == 真
真 且(&&) 假 == 假
假 且(&&) 真 == 假
假 且(&&) 假 == 假
4、练习题
结合"赋值运算符"和"逻辑运算符"做下面的题
$a = 3; $b = 5; if(($a = 8) || ($b = 9)){ $a = $a + 1; $b = $b + 1; } echo $a, '~', $b; // 9~6 /** * 分析: * 1. 用小括号包起来($a = 8)、($b = 9)的2个运算式是"赋值表达式" * 2. "赋值表达式的"返回值"就是等号右边的"值本身" * ($a = 8) 的返回值是 8 * 3. 8在做if判断的时候,8转成布尔值是true * 9在做if判断时,转成布尔值是true * 4. 逻辑或运算符(||)第一个为true,右边的第二个就不用做判断了 * 这种特性称为:逻辑运算的"短路特性" * 就是一旦从逻辑上分析出结果后,后面的表达式将不再运行 * 5. 所以$a=8、$b还是等于5,然后再各加1 * */
同理,还是这道题,稍微改变一下
$a = 3; $b = 5; if(($a == 3) && ($b = 99)){ echo $a, '~', $b; // 3~99 } /** * 1. 首先($a == 3)这个表达式运行,计算的结果为true * 2. 但是,这一个并且(&&)逻辑 * 3. 后面($b = 99)的表达式,$b被赋值为99,转化布尔值为true * 4. 然后$a是3,$b是99 * */
再改变一下这道题
$a = 3; $b = 5; if(($a > 3) && ($b = 99)){ echo $a, '-', $b; // 判断不成立,不进入这里 }else{ echo $a, '-', $b; // 3-5 } /** * 1. ($a > 3)不成立,条件为false * 2. 逻辑并且,前面的为false,后面的($b = 99)就不用看了 * 3. 因此到else里面去打印,结果$a为3、$b为5 * */
再来做一题:
逻辑运算的优先级,并且(||)的优先级,比或者(&&)高
下面的结果是打印aaa,还是bbb?
$a = 3; $b = 5; if($a == 3 && $b > 5 || $a > 3 && $b == 5){ echo 'aaa<br/>'; }else{ echo 'bbb<br/>'; // 输出 bbb } /** * if($a == 3 && $b > 5 || $a > 3 && $b == 5) * 上面这个表达式,是为了告诉我们,逻辑运算的优先级 * * 逻辑运算的优先级: * &&(并且)的优先级 比 ||(或者)的优先级高 * * 但是在开发中小括号包起来,才是正确的写法 * if(($a == 3 && $b > 5) || ($a > 3 && $b == 5)) * * * if(($a == 3 && $b > 5) || ($a > 3 && $b == 5)) * if( true && false ) || ( false && true ) * if( false ) || ( false ) * 逻辑与条件是并且的关系,if条件不成立 * 所以输出:bbb * */
5、 ! 逻辑反
一个命题如果是真命题,则其反命题,是假命题
$a = true; if($a){ echo '变量a为真<br/>'; // 变量a为真 }else{ echo '变量a不为真<br/>'; } /** * $a 既然是为真 * !$a 即$a的反命题 * 因此打印,变量a不为真 * */ if(!$a){ echo '变量a为真<br/>'; }else{ echo '变量a不为真<br/>'; // 变量a不为真 }
6、异或运算
异或运算用 xor 来表示
异或是指,两个条件必须“一个真、一个假,才为真”
/** * 例子很nice * 这个"异或"表达的是:必须一个为男,一个不为男,整体才为真 * */ $Li = '男'; $Mei = '女'; if(($Li == '男') xor ($Mei == '男')){ echo '可以结婚(一个是男,一个是女)<br/>'; // 可以结婚(一个是男,一个是女) }else{ echo '法律禁止,请去北欧<br/>'; } /* =========================================== */ $Li = '男'; $Mei = '男'; if(($Li == '男') xor ($Mei == '男')){ echo '可以结婚(一个是男,一个是女)<br/>'; }else{ echo '法律禁止,请去北欧<br/>'; // 法律禁止,请去北欧 } /* =========================================== */ $Li = '女'; $Mei = '女'; if(($Li == '男') xor ($Mei == '男')){ echo '可以结婚(一个是男,一个是女)<br/>'; }else{ echo '法律禁止,请去北欧<br/>'; // 法律禁止,请去北欧 }
八、三元运算符
语法:
条件? 返回值1 : 否则,返回值2;
如果条件为正,则返回值1,否则,返回值2
/** * 比如: * 在网站中判断一个人有没有登录 * * 如果登录,用户名不为空,则显示用户名 * 如果没有登录,用户名为空,显示"游客"两个字 * * 没用三元运算符,用if…else的写法 * */ //$user = '张三'; if(isset($user) != ''){ echo $user; }else{ echo '游客'; }
用三元运算符,可以用一行简单的达到用if else的效果
$user = '张三'; $res = $user != ''? $user : '游客'; // $res的返回值 echo $res;
熟练了,可以这样写
$user = ''; echo $user != '' ? $user : '游客';
九、递增、递减运算符
跟三元运算一样,递增、递降运算符也是一些常见的简化写
/** * 分析: * 1. "$b + 1"是一个算术运算,算出的结果是3,这个3是一个"算出结果",和$b没有关系(这个是对表达式的理解) * 2. 这个算的结果3,赋给了$a * 3. 因此$a是3,$b还是2 * */ $b = 2; $a = $b + 1; echo $a . '~' . $b,'<br/>'; // 3~2 /** * 第二种情况: * 1. "$b++"这是是一个"递增运算符",运算则必有运算结果 * 2. 问题是"$b++"的运算结果是什么呢? * 3. 答:"$b++",加加号(++)在变量后面的时候,运算结果就是$b本身 * 然后在把$b自身的值加1 * 就相当于,先return $b,然后$b = $b + 1 * */ $b = 2; $a = $b++; echo $a . '~' . $b; // 2~3
如果加加号(++)放到变量前 ++$b ,则是先把变量$b加1,然后把加1的结果返回
/** * ++$b; * 加加号(++)放到变量前 * 相当于: * 1. $b = $b + 1; * 2. return $b; * */ $b = 2; $a = ++$b; echo $a, '~', $b; // 3~3
递减 与 递增同理
/** * $b--; * $b减减: * 1. 先返回$b的值,$b的值是3 * 2. 把3赋给$a * 3. 然后$b = $b -1 * * 因此$a是3、$b是2 * */ $b = 3; $a = $b--; echo $a, '~', $b, '<br/>'; // 3~2 /** * --$b; * 减减$b: * 1. 先把$b减1,减了1后,$b变成2了 * 2. 把2赋值给$a * * 因此$a是2、$b是2 * */ $b = 3; $a = --$b; echo $a, '~', $b, '<br/>'; // 2~2
面试题
$i = 2; echo $i++ + ++$i + $i++; // 10
用JS代码分析
<script> var i = 2 console.log(i++ + ++i + i++); // 2 3 3 第一步:只算递增,递增后值的变化 // 2 + 3 + 3 第二步:把加号加上,开始运算2 + 3 = 5 // 5 + 5 第三步:i已经变成5了,两个i相加,最终等于10 // console.log(i++); // 2 // console.log(i++ + ++i); // 6 </script>
十、位运算(了解)
如果会逻辑运算符,再会二进制就会相当容易掌握位运算符
位运算符说白了,就是"二进制 + 逻辑运算"
十进制的7,转换二进制
/** * 7 / 2 = 3 余1 * 3 / 2 = 1 余1 * 1 / 2 = 0 余1 * 7转成二进制是111 * */ echo decbin(7),'<br/>'; // 111 echo 0b111; // 7
十进制的5,转成二进制
/** * 5 / 2 = 2 余1 * 2 / 2 = 1 余0 * 1 / 2 = 0 余1 * 5的二进制是 101 * */ echo decbin(5),'<br/>'; // 101 echo 0b101; // 5
灵活变通,把十进制的7,转成三进制
/** * 7 / 3 = 2 余1 * 2 / 3 = 0 余2 * 7转成三进制是 21 * 21 * 2权值是3,2*3 = 6 * 1权值是1,1*1 = 1 * */ ## JS代码 // console.log(parseInt(21, 3)); // 7
计算机里的信息都是以二进制存储的,
一个可以存储 0或1 的单元,叫做bit(位/比特)
8个位(bit)组成一个字节(Byte)
字节,是计算机里最基本的单位(虽然最小能小到位,但不可能用位来存储),最少都要占八个字节。
因此
12 / 2 = 6 余0
6 / 2 = 3 余0
3 / 2 = 1 余1
1 / 2 = 0 余1
十进制12的二进制是1100,前面用0补齐八位 0000 1100
十进制5的二进制是101,前面用0补齐八位 0000 0101
有了上面这个基础,位运算符
& 把2个二进制的值对齐,把1看成true,把0看成false,然后每个位上都做"并且"的运算
/** * 12 = 0000 1100 * 5 = 0000 0101 * &--------- * 0000 0100 */ echo 12 & 5; // 4 echo '<hr/>'; echo 0b00000100; // 4
| 把2个二进制值对齐,把1看成true,把0看成false,然后每个位上都做"或者"的运算
/** * 12 = 0000 1100 * 5 = 0000 0101 * |--------- * 0000 1102 */ echo 12 | 5; // 13 echo '<hr/>'; echo 0b00001101; // 13
^ 把二进制值对齐,把1看成true,把0看成false,然后每个位上都做"异或者"的运算(就是他俩必须不一样才为真)
/** * 12 = 0000 1100 * 5 = 0000 0101 * ^--------- * 0000 1001 */ echo 12 ^ 5; // 9 echo '<hr/>'; echo 0b00001001; // 9
~ 按位求反,求反的意思是,碰到1就变0,碰到0就变成1
/** * 12 = 0000 1100 * ~--------- * 1111 0011 * * 计算机里表示负数,是用补码的规则来计算的 * 11110011最高位是1,表示负数 * * 开始补码规则: * 计算除符号位之外,其它7位的绝对值 * 1. 1111 0011后面七位是 111 0011 * 2. 二进制的111 0011是,十进制的115 * 3. 然后再把绝对值115 减 2^7 = 128 * 115 - 128 = -13 * */ $a = 12; echo ~$a; // -13 /*** 因此: 1000 0001 -> 不要想,当然是 -1 而是 1 - 128 = -127 1111 1111 -> 111 1111 = 127 127 - 128 = -1 这就是为什么mysql数据库int型,能存 -128 ~ 127 1000 0000 -> -128 1111 1111 -> -1 0000 0000 -> 0 0111 1111 -> 127 ***/
<< 移位运算
/*** 5 = 0000 0101 <<--------- 000 0101 往左移动1位,最左边的零掉下去1位 0000 101 右边就空出来一个 0000 1010 空出来用0来补,后面缺的1位补上一个0 0000 1010 -> 转成十进制是10,相当于乘2的效果 ***/ echo 5 << 1; // 往左移动1位,输出10 echo '<hr/>'; echo 0b00001010; // 10 // 5 << 2;移动2位打印是20
>> 同理往右移动一位
/*** 5 = 0000 0101 >>--------- 0000 010 向右移动1位,把最右边的1挤掉了 000 0010 左边空出了1位 0000 0010 左边空出的1位补0 0000 0010 -> 转十进制是2,相当于除2的效果 ***/ echo 5 >> 1; // 2 echo '<hr/>'; echo 0b00000010; // 2
总结
燕子十八老师:视频课程顺序:
1.算数运算符
2.比较运算符
3. 类型转换
4.字符串运算符(“.”点拼接运算)
5.赋值运算符(“=”等号)
6.运算符运算完毕后的结果
5.赋值运算符
7.逻辑运算符
8.三元运算符
9.递增、递减运算符
10.位运算符
燕子十八老师:ppt教案顺序:
赋值运算符
算术运算符
递增运算符
逻辑运算符
比较运算符
字符串运算符
三元运算符
位运算符
这世界不缺善良,缺的是加了理智的善良。
这句话说的接近大智慧了