我正在阅读Opencv上的一篇文章,并且发现了这个:
for( i = 0; i < (faces ? faces->total : 0); i++ )
{
CvRect* r = (CvRect*)cvGetSeqElem(faces, i);
}
这条线应该是什么意思:
i < (faces ? faces->total : 0)
答案 0 :(得分:4)
(faces ? faces->total : 0)
次测试faces
。如果是,则返回faces->total
并与i
进行比较。否则,如果评估为false,则将i
与0
进行比较。
答案 1 :(得分:4)
编辑:根据Femaref的评论,我的下面的代码(原始回复)不等于。调用faces
可能会修改cvGetSeqElem
,这反过来意味着faces->total
也可能会被修改。因此,条件可能会在每次迭代中发生变化,如果faces
为空(0
),则循环退出。
然而,令人困惑的是(得到了我!)。您可以轻松检查faces
是否为null并退出循环。循环计数器可能在每次迭代中发生变化,取决于变异它的cvGetSeqElem
函数,并且只是bleh。
这是一个名为conditional operator的简写语句。它与以下内容大致相同:
int count = 0;
if( faces )
count = faces->total;
for( i = 0; i < count; i++ ) {
CvRect* r = (CvRect*)cvGetSeqElem(faces, i);
}
因此,如果faces
为空,count
为0
,并且循环体永远不会执行,因为第一次测试失败。当然,你可以先检查一下是否为null并避免整个过程。那段代码是丑陋的IMO。
if( faces ) {
// do loop
}
另外,如果faces->total
是&gt; 1然后你只是浪费周期,只有cvGetSeqElem
返回的最后一个值会持续存在。当然,这个功能可能会产生其他依赖的副作用,这会使代码比现在更复杂。
答案 2 :(得分:2)
等同于
int output;
if(faces == 0)
output = 0;
else
output = faces->total;
(注意:这只是对for循环中的部分的解释,而不是替换)
这是C中的一个技巧。faces
实际上是指向结构的指针(->
解除引用可见)。 C中没有布尔类型,0表示false,其他每个值都为true。在这种情况下,指针隐式转换为int,而不是conditional operator中的布尔值。
一旦指向结构的指针为NULL
,循环就会终止。 faces
已更改cvGetSeqElem
。
答案 3 :(得分:2)
它正在迭代到结构中的成员值。
如果结构指针为NULL,则它迭代零次。
这是防止取消引用NULL指针的安全功能。
答案 4 :(得分:0)
ternary operator:&#34;如果faces为true,则faces-&gt; total,否则为0&#34;。