2

我在代码库中看到了一段类似的 perl 代码,想知道这(设置i=100)是否是摆脱 for 循环的好方法?这有什么陷阱吗?

int a[100];

...

bool check_if_array_contains_29()
{
    bool result = false;
    for(int i=0; i<100; ++i)
    {
        if(a[i] == 29)
        {
            result = true;
            i = 101;
        }
    }
    return result;
}

这更像是我会做的。

bool check_if_array_contains_29()
{
    bool result = false;
    for(int i=0; i<100 && !result; ++i)
    {
        if(a[i] == 29)
        {
            result = true;
        }
    }
    return result;
}

编辑-1:

我不是在寻找 perl 中的 oneliner 来实现该功能。真正的代码(功能)要复杂得多。这只是我简化以解释我的观点的一个示例(for 循环的提前终止)。

4

6 回答 6

9

你为什么不这样做:

bool check_if_array_contains_29()
{
    for(int i=0; i < 100; ++i)
    {
         if (a[i] == 29)
           return true;
    }
    return false;
}

编辑:
我知道有些人觉得多个 return 语句太可怕了,应该不惜一切代价避免,但对我来说,在像所提供的方法中具有多个 return 使代码更易于阅读和遵循。

编辑 2:
附加版本,因此如果该方法需要有一些副作用或执行一些附加操作,您可以使用 break 语句,或者您可以调整 for 循环条件,或者您可以添加一些标签和一些 goto。

bool check_if_array_contains_29_take2()
{
    bool result = false;
    for (int i=0; i < 100; ++i)
    {
        if (a[i] == 29)
        {
            result = true;
            break;
        }
    }

    // Do Other Stuff
    return result;
}

bool check_if_array_contains_29_take3()
{
    bool result = false;
    for (int i=0; !result && i < 100; ++i)
    {
        result = a[i] == 29;
    }

    // Do Other Stuff
    return result;
}

// Special edition for those who can't get enough goto
bool check_if_array_contains_29_and_do_more_stuff_without_early_return()
{
    bool result = false;
    for (int i=0; i < 100; ++i)
    {
        if (a[i] == 29)
        {
            result = true;
            break;
        }
    }

    if (!result)
        goto error;

    // Do some other stuff in the code here
    goto done;

done:
    return result;
error:
    result = false;
    goto done;
}
于 2012-06-29T18:28:31.727 回答
4

有什么问题break或者只是return true在循环内部?它清楚地传达了意图,并且不依赖于循环条件。

于 2012-06-29T18:28:11.523 回答
3

在 Perl 中,您可以使用last(可能带有标签)来提前退出循环。

要查找 29 在 array 中的第一次出现@x,您将使用List::MoreUtils::first_index

 my $i = first_index { $_ == 29 } @x;
 $i > -1 or die "Cannot find 29 in array\n";

对于循环变量的愚蠢赋值,我想不出任何技术陷阱,但它完全是 WTF,并且让阅读代码的人感到困惑是一个非常重要的陷阱。

于 2012-06-29T18:36:23.827 回答
2

在 C 中,您将使用break,它退出最小的循环(指令所在的循环):

for(...) {
    if (a[i] == 29) {
        result = true;
        break;
    }
}

但是在您的情况下,您可以简单地exit使用整个功能:

for(...) {
    if (a[i] == 29)
        return true;
}
于 2012-06-29T18:41:34.200 回答
2

正确的方法是使用breakC 或lastPerl中的指令

int a[100];

...

bool check_if_array_contains_29()
{
    bool result = false;
    for(int i=0; i<100; ++i)
    {
        if(a[i] == 29)
        {
            result = true;
            break;
        }
    }
    return result;
}

虽然第一种方式是可以接受的。关于第二个,是有效的,但我不会使用它,因为有更简单的方法可以做到这一点。

于 2012-06-29T18:35:58.333 回答
1

使用break

    bool check_if_array_contains_29()
    {
       bool result = false;
       for(int i=0; i<100; ++i)
       {   
          if(a[i] == 29)
          {
            result = true;
            break;
          }
        }
     return result;
    }
于 2012-06-29T18:36:12.767 回答