这是在C或Perl中终止for循环的合适方法吗?

时间:2012-06-29 18:24:53

标签: c perl coding-style

我在代码库中看到了一段类似的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循环)。

6 个答案:

答案 0 :(得分:9)

为什么你不这样做:

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

编辑:
我知道有些人觉得多个返回语句都很糟糕,应该不惜一切代价避免,但对我来说,在所提出的方法中有多个返回值会使代码更易于阅读和遵循。

编辑2:
其他版本,以便如果方法需要有一些副作用或执行一些额外的操作,你可以使用break语句,或者你可以调整for循环条件,或者你可以添加一些标签和一些gotos。

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;
}

答案 1 :(得分:4)

循环中break或简称return true有什么问题?它清楚地传达了意图,而不依赖于循环条件。

答案 2 :(得分:3)

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

要查找数组@x中第一次出现29,请使用List::MoreUtils::first_index

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

我无法想到对循环变量的愚蠢分配有任何技术上的缺陷,但它是一个完整的WTF,让阅读代码的人感到困惑是一个非常重要的陷阱。

答案 3 :(得分:2)

正确的方法是使用C中的break指令或Perl中的last

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;
}

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

答案 4 :(得分:2)

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

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

但在你的情况下,你只需exit整个功能:

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

答案 5 :(得分: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;
    }