2

有什么理由写:

double pop(void)
{
    if (sp > 0)
        return val[--sp];
    else {
        printf("error: stack empty\n");
        return 0.0;
    }
}

代替:

double pop(void)
{
    if (sp > 0)
        return val[--sp];

    printf("error: stack empty\n");
    return 0.0;
}

除了风格?不会return停止功能吗?

4

7 回答 7

10

正如其他人所说,它们是等价的,但通常的习惯用法是在“常规情况”中执行流经函数的末尾,而异常情况则提前出现(这源于这样一个事实,否则,在没有异常,你会得到一百万个带有许多错误检查的代码嵌套大括号)。

所以,可能我会颠倒条件并写:

double pop(void)
{
    // First parameters/preconditions/... checks
    if (sp <= 0)
    {
        // Exceptional case, get out early
        printf("error: stack empty\n");
        return 0.;
    }
    // We get here if everything is ok - regular case
    return val[--sp];
}

顺便说一句,在使用此签名编写通用堆栈函数时,我可能会返回比0.堆栈下溢更重要的东西——可能是 NaN 或类似的东西(如果平台支持)。

于 2013-09-09T00:25:29.417 回答
3

他们都是一回事。第二个片段更易于阅读,因为它具有较少的词法结构并且if条件较短。否则,他们都有同样的恐惧困难。

根据上下文,您可能需要前者或后者。这完全取决于您希望代码传达的语义。

例如,如果其中一个分支是例外情况(递归函数的错误或基本情况),您将使用后一种形式。但是,如果这两种情况具有相同的语义(发生/意义几乎相同的替代方案),您将使用前一个片段。

因此,你会写

int factorial (int x)
{
    if (x <= 1)
        return 1;
    return x * factorial (x - 1);
}

int act_on_contents_of_file(char *fname)
{
    FILE *f = fopen(fname, "r");
    if (f == NULL) { /* error opening */
        perror(...);
        return -1;
    }
    ....
    return 0;
}

虽然你会写

int collatz(int x)
{
    if (x % 2 == 0)
        return collatz(x / 2);
    else
        return collatz(3 * x + 1);
}
于 2013-09-09T00:19:18.030 回答
2

首选代码段是您获得最高报酬的代码段。这意味着您的商店应该有编程标准,并且应该在这些标准中讨论这样的示例。

于 2013-09-09T01:54:42.010 回答
2

它们在您的示例中是等效的,并且都将编译为相同的二进制文件。区别只是味道。第一个例子很明显,如果if为假,则执行一个条件。

第二个有这个缺点:不阅读 if 子句的主体,特别是如果它很长,如果不研究主体的全部内容,您就无法确定何时调用最后一个代码(想想嵌套范围与一些分支其他返回时不返回)。

于 2013-09-09T00:23:08.887 回答
2

它们是等价的。第一个版本强调只有两个条件,但第二个实现了相同的结果。

printf()应该是向fprintf()报告错误,而stderr不是stdout;这就是错误通道的用途。

于 2013-09-09T00:21:55.510 回答
1

他们都是一回事。在不知道您正在编写的代码的上下文的情况下,这两个片段都不比另一个更可取。

于 2013-09-09T00:20:40.380 回答
-1

他们都是一回事。第一个片段更可取。

于 2013-09-09T00:19:47.907 回答