Php 嵌套三元运算符的优先顺序
前几天我在课堂上,展示了以下代码片段:Php 嵌套三元运算符的优先顺序,php,operators,Php,Operators,前几天我在课堂上,展示了以下代码片段: <?php //Intialize the input $score=rand(50,100); //Determine the Grade $grade=($score>=90)?'A':( ($score>=80)?'B':( ($score>=70)?'C':( ($score>=60)?'D':'F'))); //Output the Results echo "<h1>A score
<?php
//Intialize the input
$score=rand(50,100);
//Determine the Grade
$grade=($score>=90)?'A':(
($score>=80)?'B':(
($score>=70)?'C':(
($score>=60)?'D':'F')));
//Output the Results
echo "<h1>A score of $score = $grade</h1>";
?>
当时我对嵌套的三元运算符中的操作顺序提出了质疑,认为它们将从内到外进行计算,也就是说,如果$score>=60,它将首先进行计算,然后如果$score>=70,等等——无论分数是多少,每次都会对整个堆栈进行计算
在我看来,这个结构应该遵循与数学运算符相同的优先顺序——首先解析最里面的一组括号,然后进行运算,除非三元数有一些独特的运算顺序
不幸的是,课堂上的讨论很快就变成了赢得辩论,而我真的只是想了解它是如何运作的。所以我的问题有两个:
(1) 这句话怎么解释我?为什么
及
(2) 是某种堆栈跟踪或单步执行工具,可以让我观察代码如何执行?三值运算符短路。只计算适当的操作数。这意味着,在实际测试之前,paren并不重要
echo false ? (crash() / 0) : "Worked.";
从左到右: 那么它将评估在左边的是什么?并在此基础上,评估以下内容的第一或第二面: 您可以加入一个具有副作用的函数调用来演示这一点:
function p($a,$b) { echo $a . " >= " . $b; return $a>=$b; }
$grade=(p($score,90))?'A':(
p($score,80)?'B':(
p($score,70)?'C':(
p($score,60)?'D':'F')));
三元运算符是左关联的,但在应用括号后,它从右向左求值 您可以使用
xdebug
或phpdbg
作为步骤调试器,逐步调试代码并查看其计算结果
周围还有VulcanLogicDumper,它显示了以下说明:
与if-elseif-else结构相比
line # * op fetch ext return operands
---------------------------------------------------------------------------------
3 0 > SEND_VAL 50
1 SEND_VAL 100
2 DO_FCALL 2 $0 'rand'
3 ASSIGN !0, $0
5 4 IS_SMALLER_OR_EQUAL ~2 90, !0
5 > JMPZ ~2, ->8
6 > QM_ASSIGN ~3 'A'
7 > JMP ->24
6 8 > IS_SMALLER_OR_EQUAL ~4 80, !0
9 > JMPZ ~4, ->12
10 > QM_ASSIGN ~5 'B'
11 > JMP ->23
7 12 > IS_SMALLER_OR_EQUAL ~6 70, !0
13 > JMPZ ~6, ->16
14 > QM_ASSIGN ~7 'C'
15 > JMP ->22
8 16 > IS_SMALLER_OR_EQUAL ~8 60, !0
17 > JMPZ ~8, ->20
18 > QM_ASSIGN ~9 'D'
19 > JMP ->21
20 > QM_ASSIGN ~9 'F'
21 > QM_ASSIGN ~7 ~9
22 > QM_ASSIGN ~5 ~7
23 > QM_ASSIGN ~3 ~5
24 > ASSIGN !1, ~3
10 25 ADD_STRING ~11 '%3Ch1%3EA+score+of+'
26 ADD_VAR ~11 ~11, !0
27 ADD_STRING ~11 ~11, '+%3D+'
28 ADD_VAR ~11 ~11, !1
29 ADD_STRING ~11 ~11, '%3C%2Fh1%3E'
30 ECHO ~11
31 > RETURN 1
line # * op fetch ext return operands
---------------------------------------------------------------------------------
3 0 > SEND_VAL 50
1 SEND_VAL 100
2 DO_FCALL 2 $0 'rand'
3 ASSIGN !0, $0
5 4 IS_SMALLER_OR_EQUAL ~2 90, !0
5 > JMPZ ~2, ->8
6 > QM_ASSIGN ~3 'A'
7 > JMP ->24
6 8 > IS_SMALLER_OR_EQUAL ~4 80, !0
9 > JMPZ ~4, ->12
10 > QM_ASSIGN ~5 'B'
11 > JMP ->23
7 12 > IS_SMALLER_OR_EQUAL ~6 70, !0
13 > JMPZ ~6, ->16
14 > QM_ASSIGN ~7 'C'
15 > JMP ->22
8 16 > IS_SMALLER_OR_EQUAL ~8 60, !0
17 > JMPZ ~8, ->20
18 > QM_ASSIGN ~9 'D'
19 > JMP ->21
20 > QM_ASSIGN ~9 'F'
21 > QM_ASSIGN ~7 ~9
22 > QM_ASSIGN ~5 ~7
23 > QM_ASSIGN ~3 ~5
24 > ASSIGN !1, ~3
10 25 ADD_STRING ~11 '%3Ch1%3EA+score+of+'
26 ADD_VAR ~11 ~11, !0
27 ADD_STRING ~11 ~11, '+%3D+'
28 ADD_VAR ~11 ~11, !1
29 ADD_STRING ~11 ~11, '%3C%2Fh1%3E'
30 ECHO ~11
31 > RETURN 1
我将尝试解释操作码中的第一个JMPZ,以了解它是如何计算的:
感兴趣的是第5行,操作码5:
5>JMPZ~2,->8
这意味着:如果compare with 90(操作码4)为false,则跳转到操作码8
警告:->8
并不意味着跳到第8行
现在,什么是操作码8?与80的比较
68>是小于还是等于~480!0
现在可以肯定地说,这并不像您从内到外(90->60->70)所期望的那样进行计算,而是类似于if-elseif-else结构(90->80->70)。PHP尊重括号。最内层的
(…)
中的表达式首先被计算,就像我们在小学里被教的那样
PHP是不寻常的,因为三元运算符是。这意味着在没有括号的情况下,三元表达式从左到右求值
但在这种特殊情况下,括号强制表达式从右向左求值。此代码相当于:
if ($score >= 90) {
$grade = 'A';
}
elseif ($score >= 80) {
$grade = 'B';
}
elseif ($score >= 70) {
$grade = 'C';
}
...
这对你自己来说非常容易测试。对于那些知道如何回答的人来说非常简单谢谢你的回答,但是根据Rob和他的链接,三元结构实际上是从右到左的,一旦它分析了问号左边的陈述。我喜欢在三元组中插入函数调用以使其报告的想法。我不知道你能做那种事。干杯,谢谢詹斯·安德烈。我试图让xdebug在NetBeans上工作,但徒劳。出于许多原因,我现在转到SublimiteText2。您使用什么IDE生成此报告?干杯这里显示的报告不是由IDE生成的,而是由-Tab“VLD操作码”生成的。如果要在自己的计算机上执行此操作,可以尝试VLD扩展:。有很多教程介绍如何将xdebug与Netbeans结合起来。也许这会有所帮助:感谢关于关联性的那一点,通过这一点,我能够找到:哪个回答了我要问的问题,哪个是“什么是(真?假:假?真:真)的答案?为什么?”堆叠的三元运算符的处理顺序与大多数其他运算符相反,特别是算术运算符。感谢调试建议,Ignacio