【问题标题】:C: Trying to print an error from a functionC:试图从函数中打印错误
【发布时间】:2020-10-26 00:36:08
【问题描述】:

我正在创建一个函数,该函数从两行输入中获取截距并将其显示为一个点。它大部分时间都有效,但是当没有交叉点(线平行)时,我(-inf,-inf)。我试图让该功能改为打印“错误”。这是我尝试过的,但它仍然返回相同的东西。

Point getIntercept (Line a, Line b) {
    Point intercept;    
    if (a.m == b.m) {
        printf("Error");
    } else {
        double x = (a.b - b.b) / (b.m - a.m); //solves for x
        double y = a.m * x + a.b; //plugs in for y
        intercept.x = x;
        intercept.y = y;
        return intercept;
    }
}

【问题讨论】:

  • 那么在你打印Error之后,return的作用是什么?
  • 我还想知道输出是否是行缓冲的,并且因为您没有写换行符,所以您可能还没有看到打印的Error。无论如何,如上所述,在这种情况下,您当然需要一个适当的返回值。
  • @KamilCuk 它打印与没有 if 语句时相同的内容,这意味着如果有一个则打印一个截距,如果没有则打印 (-inf, -inf)
  • @BepisKid 你看到的是未定义的行为,如果没有的话。不要依赖它。如果您打开编译器警告,您可能会看到类似“控制到达非无效函数的结尾”之类的内容。决定在没有拦截时使用的返回值,并返回它(然后在调用者中测试它)。
  • 你的算法是错误的。如果您想知道这些线是否平行,请测试a.m == b.m,然后在函数的第二行除以零之前执行此操作!

标签: c function printf


【解决方案1】:

没有cmets或细节的简短回答:

Point getIntercept(Line a, Line b)
{
  Point interception;
  if (a.m != b.m) {
    interception.x = fabs(b.b - a.b) / fabs(b.m - a.m);
    interception.y = a.m * interception.x + a.b;
  }
  return interception;
}

您可以像这样实现错误检查:

int intersect (Line a, Line b)
{
    return a.m != b.m || a.b == b.b;
}

然后这样称呼它:

if (intersect (a, b)) {
  Point iab = getIntercept(a, b);
  printf("interception at: %f %f\n", iab.x, iab.y);
} else {
  puts ("line a, b don't intersect");
}

带有 cmets 和详细信息的更长答案:

#include <stdio.h>
#include <math.h>
 
typedef struct Point
{
  double x;
  double y;
} Point;
 
typedef struct Line
{
  double m;
  double b;
} Line;
 
Point getIntercept(Line a, Line b)
{
  Point interception;
  if (a.m != b.m) {
    interception.x = fabs(b.b - a.b) / fabs(b.m - a.m);
    interception.y = a.m * interception.x + a.b;
  }
  return interception;
}
 
int intersect (Line a, Line b)
{
    return a.m != b.m || a.b == b.b;
}
 
int main ()
{
  Line a = {0.75, 0}; // a: y = 0.75x + 0
  Line b = {-0.5, 2}; // b: y = -0.5x + 2
  Line c = {0.75, 2}; // c: y = 0.75x + 2 => paralell to a
 
  if (intersect (a, b)) {
    Point iab = getIntercept(a, b);
    printf("interception at: %f %f\n", iab.x, iab.y);
  } else {
    puts ("line a, b don't intersect");
  }
  
  if (intersect (a, c)) {
    Point iac = getIntercept(a, c);
    printf("interception at: %f %f\n", iac.x, iac.y);
  } else {
    puts ("line a, c don't intersect");
  }
}

结果(从长答案 sn-p 生成的输出):

interception at: 1.600000 1.200000                                                                                                                                       
line a, c don't intersect 

正如其他用户已经说过的那样:在这种情况下,要么抛出错误,要么返回有用的东西。

【讨论】:

  • @DavidC.Rankin 感谢您的反馈。是的,我只有来自在线编译器的代码。我可以编辑它。但是当我返回结构点时,我可以检查 NULL 吗:if (result == NULL)?我认为它必须是一个指针 - 不是吗?
  • 所以基本上if (a.m == c.m &amp;&amp; a.b != c.b) 线永远不会相交。你可以把它写成一个快速函数,它接受两个 Line 作为参数,例如int intersect (Line a, Line b) { return a.m != b.m || a.b == b.b; }Line Intercept 2
  • @DavidC.Rankin 我已经实施了您的变更请求。并感谢有用的提示。我自己对 C/C++ 还是很陌生 - 我通常使用 Java 进行开发。
  • 您的更改很好——因为Point 无法返回指示线是否相交的信息,如果我正在编写它,我可能会将Point 作为参数传递并具有该函数返回1/0 以指示success/failure - 或类似于:Line Intercept 3。这里所有参数都是指针(它们比PointLine 本身要小),它允许您对该内存地址进行操作并在函数内进行更改。如果您只是按值传递 Point - 任何更改都将丢失 :)
  • @DavidC.Rankin 我完全明白这一点。啊,所以这类似于 PHP,您可以通过 &var 引用传递参数。我在 Java 中已经习惯了,只有当你有原语时,你总是通过引用对象来调用函数。但是结构不是c中的类,所以是的。看到这一切是如何联系起来的,并且 C 的概念更接近机器代码级别,这很有趣。是否有理由返回 int 而不是 bool?更多州?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多