Labfans是一个针对大学生、工程师和科研工作者的技术社区。 论坛首页 | 联系我们(Contact Us)
MATLAB爱好者论坛-LabFans.com
返回   MATLAB爱好者论坛-LabFans.com > 其它 > 资料存档 > MATLAB技术文章
MATLAB技术文章 MATLAB Technical Articles From Mathworks
 
 
主题工具 显示模式
旧 2019-11-23, 21:01   #1
poster
高级会员
 
注册日期: 2019-11-21
帖子: 3,006
声望力: 66
poster 正向着好的方向发展
默认 Interesting Matlab puzzle – analysis

Last week I presented a seemingly-innocent Matlab code snippet with several variants, and asked readers to speculate what its outcomes are, and why. Several readers were apparently surprised by the results. In today’s post, I offer my analysis of the puzzle.
The original code snippet was this:

function testtryif (false) or (true)disp('Yaba');elsedisp('Daba');endcatchdisp('Doo!');endend

With the following variants for the highlighted line #3:

if (false) or (true) % variant #1 (original)if (true) or (false) % variant #2if (true) or (10< 9.9) % variant #3if true or 10< 9.9 % variant #4if 10> 9.9 or 10< 9.9 % variant #5



Variant #1: if (false) or (true)

The first thing to note is that or is a function and not an operator, unlike some other programming languages. Since this function immediately follows a condition (true), it is not considered a condition by its own, and is not parsed as a part of the “if” expression.
In other words, as Roger Watt correctly stated, line #3 is actually composed of two separate expressions: if (false) and or(true). The code snippet can be represented in a more readable format as follows, where the executed lines are highlighted:

if (false)or (true)disp('Yaba');elsedisp('Daba');end

Since the condition (false) is never true, the “if” branch of the condition is never executed; only the “else” branch is executed, displaying ‘Daba’ in the Matlab console. There is no parsing (syntactic) error so the code can run, and no run-time error so the “catch” block is never executed.
Also note that despite the misleading appearance of line #3 in the original code snippet, the condition only contains a single condition (false) and therefore neither short-circuit evaluation nor eager evaluation are relevant (they only come into play in expressions that contain 2+ conditions).
As Rik Wisselink speculated and Michelle Hirsch later confirmed, Matlab supports placing an expression immediately following an “if” statement, on the same line, without needing to separate the statements with a new line or even a comma (although this is suggested by the Editor’s Mlint/Code-Analyzer). As Michelle mentioned, this is mainly to support backward-compatibility with old Matlab code, and is a discouraged programming practice. Over the years Matlab has made a gradual shift from being a very weakly-typed and loose-format language to a more strongly-typed one having stricter syntax. So I would not be surprised if one day in the future Matlab would prevent such same-line conditional statements, and force a new line or comma separator between the condition statement and the conditional branch statement.
Note that the “if” conditional branch never executes, and in fact it is optimized away by the interpreter. Therefore, it does not matter that the “or” function call would have errored, since it is never evaluated.

Variant #2: if (true) or (false)

In this variant, the “if” condition is always true, causing the top conditional branch to execute. This starts with a call to or(false), which throws a run-time error because the or() function expects 2 input arguments and only one is supplied (as Chris Luengo was the first to note). Therefore, execution jumps to the “catch” block and ‘Doo!’ is displayed in the Matlab console.
In a more verbose manner, this is the code (executed lines highlighted):

function testtryif (true)or (false)disp('Yaba');elsedisp('Daba');endcatchdisp('Doo!');endend

Variant #3: if (true) or (10< 9.9)

This is exactly the same as variant #2, since the condition 10< 9.9 is the same as false. The parentheses around the condition ensure that it is treated as a single logical expression (that evaluates to false) rather than being treated as 2 separate arguments. Since the or() function expects 2 input args, a run-time error will be thrown, resulting in a display of ‘Doo!’ in the Matlab console.
As Will correctly noted, this variant is simply a red herring whose aim was to lead up to the following variant:

Variant #4: if true or 10< 9.9

At first glance, this variant looks exactly the same as variant #3, because parentheses around conditions are not mandatory in Matlab. In fact, if a || b is equivalent to (and in many cases more readable/maintainable than) if (a) || (b). However, remember that “or” is not a logical operator but rather a function call (see variant #1 above). For this reason, the if true or 10< 9.9 statement is equivalent to the following:

if trueor 10< 9.9...

Now, you might think that this will cause a run-time error just as before (variant #2), but take a closer look at the input to the or() function call: there are no parentheses and so the Matlab interpreter parses the rest of the line as space-separated command-line inputs to the or() function, which are parsed as strings. Therefore, the statement is in fact interpreted as follows:


if trueor('10
poster 当前离线   回复时引用此帖
 


发帖规则
不可以发表新主题
不可以发表回复
不可以上传附件
不可以编辑自己的帖子

启用 BB 代码
论坛启用 表情符号
论坛启用 [IMG] 代码
论坛启用 HTML 代码



所有时间均为北京时间。现在的时间是 23:05


Powered by vBulletin
版权所有 ©2000 - 2025,Jelsoft Enterprises Ltd.