Go to comments

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

记住这句话:在取模运算的时候,余数的符号和被除数的符号是一致。

image.png

被除数是正数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、数字转布尔(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

image.png

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
 *
 * }
 *
 */

七、逻辑运算符

逻辑运算符有这么几种:

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教案顺序:

赋值运算符

算术运算符

递增运算符

逻辑运算符

比较运算符

字符串运算符

三元运算符

位运算符


这世界不缺善良,缺的是加了理智的善良。

这句话说的接近大智慧了




Leave a comment 0 Comments.

Leave a Reply

换一张