return 语句中的奇怪表达式
Posted
技术标签:
【中文标题】return 语句中的奇怪表达式【英文标题】:Strange expression in the return statement 【发布时间】: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 很好。
【参考方案1】:
(*arr < 0)
将数组的第一个元素与零进行比较。表达式的结果可以是1
(第一个元素为负)或0
(第一个元素为正或零)。所以,负元素个数就是这个表达式加上数组尾部的负元素个数。
【讨论】:
【参考方案2】:原则是,不是在被检查的元素上保留索引,因为arr
是一个指针并且修改它不会更改数据,因此可以使用arr
本身作为数组数据的迭代器。
所以,*arr < 0
检查当前指向的元素是否为负(如果是,它将产生1
,如果不是,则产生0
),++arr
将光标递增到数组中的下一个位置,即然后递归传递以检查数组的其余部分。
这是使用列表的函数式语言中一个众所周知的想法,您经常处理列表的第一个元素(head)并递归处理列表的其余部分(尾巴)。
【讨论】:
现在我明白了,即 (*arr 没错。1
和 true
在 C 中是相同的值
2 也是真的 ... ;-)【参考方案3】:
*arr
指向arr
数组的第一个元素(或者,更准确地说,是arr
在这个特定调用中传递给函数的部分)。
count_negative( ++arr, n-1 )
是一个递归调用,但由于++arr
,在此调用中,我们计算数组的下一个元素和n-1
参数,与if ( n > 0 )
一起保证我们将仅计算@ 内的元素987654328@数组。
【讨论】:
以上是关于return 语句中的奇怪表达式的主要内容,如果未能解决你的问题,请参考以下文章