【问题标题】:Is divide by zero an error or an exception?除以零是错误还是异常?
【发布时间】:2011-03-25 18:18:14
【问题描述】:

基本上我想知道如何区分错误和异常。在某些编程语言中,访问不存在的文件会引发错误,而在其他编程语言中则会引发异常。你怎么知道某件事是错误还是异常?

【问题讨论】:

  • 在许多语言中,异常不存在或者是唯一的(语言集成,广泛使用 - 即在实践中相关)错误处理机制。其他语言有几种错误处理机制。在这两种情况下,可能存在分歧应该归为哪一类。我认为没有与语言无关的答案。

标签: exception programming-languages error-handling


【解决方案1】:

像其他任何东西一样 - 你要么测试它,要么阅读文档。根据语言,它可以是“错误”或“异常”。

例如。

C:

崩溃并给出除以零错误。

鲁比:

>> 6 / 0
ZeroDivisionError: divided by 0
from (irb):1:in `/'
from (irb):1

(ZeroDivisionError 实际上是一个例外。)

Java:

代码:

int x = 6 / 0;

输出:

Exception in thread "main" java.lang.ArithmeticException: / by zero

【讨论】:

  • ZeroDivisionError 是一个例外
  • 啊,你是对的。我更新了它,使用明显的 C 作为错误之一。
  • +1 表示“知道的唯一方法是测试它或阅读文档”。
【解决方案2】:

取决于语言

  • 有些语言没有例外
  • 某些语言不会对所有内容都使用异常。


例如,在 PHP 中:

  • 有例外情况
  • 但除以 0 不会引发异常:只是引发警告 - 不会停止脚本的执行。

以下部分代码:

echo 10 / 0;
echo "hello, world!";

会给出这个结果:

Warning: Division by zero in /.../temp.php on line 5
hello, world!

【讨论】:

    【解决方案3】:

    errorexception 这两个术语通常用作行话术语,其含义因使用它们的编程生态系统而异。

    条件

    此响应遵循Common Lisp 的引导,并采用术语条件 作为引用程序中“有趣情况”的非判断方式。

    是什么让程序条件“有趣”?让我们考虑实数被零除的情况。在绝大多数情况下,一个实数除以另一个实数,结果是另一个普通的普通的良善实数。这些是“常规”或“无趣”的案例。但是,在除数为零的情况下,从数学上讲,结果是不确定的。该程序现在处于“有趣”或“异常”的状态。

    一旦我们采用实数的数学理想并将其建模为IEEE-format floating point number,它就会变得更加复杂。如果我们除以 1.0 / 0.0,IEEE 标准(大部分)说结果实际上是另一个浮点数,安静的 NaN Infinity。由于结果不再像普通的旧实数那样表现,因此程序条件再次“有趣”或“异常”。

    分类条件

    问题是:当我们遇到有趣的情况时应该怎么做?答案取决于上下文。在对程序条件进行分类时,以下问题很有用:

    1. 这种情况发生的可能性有多大:确定、可能、不太可能、不可能?
    2. 如何检测到条件:程序故障、可分辨值、信号/处理程序(又名exception handling)、程序终止?
    3. 应该如何处理条件:忽略它,执行一些特殊操作,终止程序?

    这些问题的答案产生了 4 x 4 x 3 = 48 个不同的案例——当然更多的案例可以通过进一步的标准来区分。这将我们带到了问题的核心。我们有两个以上的案例,但只有两个标签,errorexception,可以应用于它们。不用说,有很多可能的方法可以将 48+ 案例分为两组。

    例如,可以说任何涉及程序故障的事情都是错误,其他任何事情都是异常。或者任何涉及语言内置exception handling 设施的东西都是异常,其他任何东西都是错误。可能性很多。

    示例

    文件结束

    在读取和处理字符流时,肯定会到达文件末尾。在 C 中,这个事件是通过 I/O 函数的一个可区分的返回值来检测的,即所谓的 error 返回值。因此,有人说 EOF 错误

    除以零

    在简单的计算器程序中将两个用户输入的数字相除时,即使用户输入的除数为零,我们也希望给出有意义的结果。在某些 C 环境中,除以零会产生一个 信号 (SIGFPE),该信号必须由信号处理程序处理。信号有时在 C 社区中被称为 exceptions,而令人困惑的是,有时被称为程序 error 信号。在其他 C 环境中,应用 IEEE 浮点规则,除以零将导致 NaN 值。 C 环境会很高兴地不知道该值,认为它既不是异常也不是错误

    运行时加载失败

    程序经常在运行时动态加载其程序代码(例如类、DLL)。由于缺少文件,这可能会失败。 C 没有提供检测或从这种情况中恢复的标准方法。程序会不自觉地终止,人们经常将这种情况称为致命的异常。在 Java 中,这将被称为链接错误

    Java 的 Throwable 层次结构

    Java 的异常处理系统将所谓的Throwable 类层次结构分为两个主要组。 Error 的子类旨在表示无法恢复的情况。 Exception 的子类用于可恢复的条件,进一步细分为检查异常(用于可能的情况)和未检查的异常(用于不太可能的情况)。不幸的是,这些类别之间的界限定义不明确,您经常会发现其语义表明它们属于不同类别的 throwable 实例。

    警惕行话

    这些例子表明 errorexception 的含义充其量是模糊的。必须将errorexception视为行话,其含义由讨论的上下文决定。

    具有更大价值的是程序条件的显着特征。这种情况发生的可能性有多大?病情如何检测?检测到该情况时应采取什么措施?在任何需要清晰的讨论中,更适合直接回答这些问题,而不是依赖行话术语。

    【讨论】:

    • 看看Java,我可以从异常中“恢复”。作为一个程序,如果我想读取的文件不存在,我仍然可以生存,并且很好地告诉这个并要求一个实际的文件。但是在其他一些语言中,比如普通的香草 C,如果我试图读取一个不存在的文件,我就会死。当然,我可以检查该文件是否存在,但是当我尝试访问一个不存在的文件而不检查它的存在时,将不受欢迎。我认为错误不是例外,两者都是不同的。看完你的警告后,我想我可能不得不改变我的看法了。
    • 我从来没有机会在 Java 或 .NET 中工作,接触过 C 和 C++,但我更像是一名 Web 开发人员 :)
    【解决方案4】:

    异常应该表示异常活动,因此,如果您在代码中达到了已尽最大努力避免除以零的某个点,那么抛出异常(如果您能够使用您的语言)是正确的方法.

    如果检查除以零是例行逻辑(例如计算器应用程序),那么您应该在代码有机会引发异常之前在代码中进行检查。在这种情况下,这是一个错误(在用户输入中),应该这样处理。

    (这个想法是从 The Pragmatic Programmer 或 Code Complete 那里偷来的;不记得是哪个了。)

    【讨论】:

      猜你喜欢
      • 2011-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-04
      • 1970-01-01
      • 2018-01-17
      • 1970-01-01
      • 2022-11-16
      相关资源
      最近更新 更多