【问题标题】:divison by zero; is it a run time error or compile time error? [duplicate]被零除;是运行时错误还是编译时错误? [复制]
【发布时间】:2018-01-17 11:43:37
【问题描述】:

在运行此代码时,我遇到了一个浮点异常。

为什么没有打印文本zero divison error?它应该被打印出来,因为printf("zero divison error") 在被零除之前执行

#include<stdio.h>

int main()
{
    int p=0;int a=2;
    printf("zero divison error");
    printf("%d",a/p);
    // why zero divison error is not printed? 
    // i am getting floating point exception(core dumped).
}

【问题讨论】:

  • 谁应该“打印”错误?当然这是运行时错误,因为分母在运行时会得到不同的值。
  • 标题与帖子中的问题不符。你到底在问什么?
  • 除以零是 未定义的行为(对于非 IEEE 环境中的整数类型或浮点数) - 标准没有说它会引发异常
  • 严格来说,C中没有运行时错误。任何可以编译的东西都可以运行,但是如果它调用未定义的行为,任何事情都可能发生
  • 请将程序的输出复制/粘贴到您的问题中。换句话说:当运行时错误发生时,你的程序到底打印了什么?

标签: c


【解决方案1】:

标准输出默认是行缓冲的在你的实现中printf("zero division error"); 将字符写入缓冲区,但缓冲区尚未刷新。在此处添加新行 \n 或使用 fflush(stdout); 刷新输出。如果在您的应用程序崩溃之前未刷新输出,则缓冲区的内容将丢失。


至于报错,C11 6.5.5p5

/ 运算符的结果是第一个操作数除以第二个操作数的商; % 运算符的结果是余数。在这两种操作中,如果第二个操作数的值为零,则 行为未定义。

标准中给出了一些可能发生的例子 (C11 3.4.3):

2 注意可能的未定义行为范围从完全忽略情况并导致不可预测的结果,到在翻译或程序执行期间以记录的方式表现环境特征(带有或不发出诊断消息),终止翻译或执行(发出诊断消息)

因此,使用诊断消息终止执行(您已经这样做了)只是一种可能性。 C编译器也可以拒绝编译程序,或者程序运行时可以将结果设置为0,或者42;或完全忽略计算。

当我运行程序时,我得到

% ./a.out 
zsh: floating point exception (core dumped)  ./a.out

这对应于以SIGFPE结尾的程序;虽然它代表 SIGnal,Floating-Point Exception,但标准规定可以引发 SIGFPE

错误的算术运算,例如零除法或运算 导致溢出

在调用信号处理程序的那一刻,不再知道实际操作是什么,因此不会打印其他诊断信息。

【讨论】:

  • @Fabien 现在是
  • @Fabien 主要问题是标题中的问题:除以零是运行时错误还是编译时错误。
  • 很好的答案,但我同意 OP 对丢失的打印件感到困惑,而不是 如何准确除零
  • 是的,我刚刚看到标题真的很混乱,与问题的内容不匹配。我将删除我的 DV。
  • "标准输出默认是行缓冲的" --> 我还没有找到 C 指定的地方。对这种常见做法有任何引用吗?
【解决方案2】:

每个人都像疯了一样投反对票,甚至没有花时间阅读您的问题,所以我转发并希望人们花时间更好地阅读问题和答案。

你的问题是为什么zero divison error这个句子没有显示,因为你printf()它在被零除之前。

答案是:

发送到标准输出的数据被缓冲,并且您没有在字符串末尾提供任何换行符,因此该行在应用程序崩溃之前保持缓冲。

在除以零之前使用fflush(stdout); 刷新stdout,或添加\n,它会正确显示。

代码审核:

#include<stdio.h>

int main()
{
    int p=0;int a=2;
    // This will show: the \n will flush the string on stdout
    printf("zero divison error\n");
    // This might not show, the operation can fail before the call to printf()
    printf("%d",a/p);
}

【讨论】:

  • 投反对票的原因是不正确的声明,例如 这将崩溃。当然,关于缓冲的部分是正确的。
  • "\n 将刷新 stdout 上的字符串" --> '\n' 经常刷新缓冲区,但 stdout 未指定为 line 缓冲。最好使用fflush(stdout);
  • 在他的上下文中,应用程序收到一个未处理的信号,所以它会崩溃:-/他甚至说它崩溃了。答案不能太笼统。我删除了那部分以满足审稿人。
猜你喜欢
  • 2020-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-14
  • 1970-01-01
相关资源
最近更新 更多