【问题标题】:Strange expression in the return statementreturn 语句中的奇怪表达式
【发布时间】:2015-01-12 23:25:09
【问题描述】:

我发现了一个让我有点惊讶的递归函数,这个函数计算了出现在数组中的所有负数:

int count_negative(int arr[], int n)
{
  if ( n > 0 )
    return (*arr < 0) + count_negative( ++arr, n - 1 );
  return 0;
}

谁能解释一下这条线:

return (*arr < 0) + count_negative( ++arr, n-1 );

谢谢

【问题讨论】:

  • 这是一个相当糟糕的递归实现;它不符合被转换为尾调用的条件,因此与迭代实现相比,性能会受到影响。
  • 这不是(*arr ...) + count_negative( ++arr, ...惹的UB吗?
  • @cdhowie:GCC 似乎 TCO 很好。

标签: c recursion return


【解决方案1】:

(*arr &lt; 0) 将数组的第一个元素与零进行比较。表达式的结果可以是1(第一个元素为负)或0(第一个元素为正或零)。所以,负元素个数就是这个表达式加上数组尾部的负元素个数。

【讨论】:

    【解决方案2】:

    原则是,不是在被检查的元素上保留索引,因为arr 是一个指针并且修改它不会更改数据,因此可以使用arr 本身作为数组数据的迭代器。

    所以,*arr &lt; 0 检查当前指向的元素是否为负(如果是,它将产生1,如果不是,则产生0),++arr 将光标递增到数组中的下一个位置,即然后递归传递以检查数组的其余部分。

    这是使用列表的函数式语言中一个众所周知的想法,您经常处理列表的第一个元素(head)并递归处理列表的其余部分(尾巴)。

    【讨论】:

    • 现在我明白了,即 (*arr
    • 没错。 1true 在 C 中是相同的值
    • 2 也是真的 ... ;-)
    【解决方案3】:

    *arr 指向arr 数组的第一个元素(或者,更准确地说,是arr 在这个特定调用中传递给函数的部分)。

    count_negative( ++arr, n-1 ) 是一个递归调用,但由于++arr,在此调用中,我们计算数组的下一个元素和n-1 参数,与if ( n &gt; 0 ) 一起保证我们将仅计算@ 内的元素987654328@数组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-19
      • 1970-01-01
      • 2012-06-25
      • 2017-07-16
      • 2013-12-12
      • 2011-10-21
      • 2014-03-16
      相关资源
      最近更新 更多