我如何用等价的结构化语句替换continue和goto语句

How can I replace continue and goto statements with structured equivalent?

本文关键字:语句 替换 continue goto 结构化 何用      更新时间:2023-10-16

我写了代码,但是我的教授说使用continuegoto是不好的做法。我试过用另一个while循环替换continue语句,但它给了我不正确的输出。continue和goto语句的结构是什么?

void getrare(int *arr, int *ordered, int len)
{
    for (int index = 0; index < len; ++index)
    {
        int n = arr[index];
        int d = 0;
        while (n)
        {
            d = n % 10;
            for (int i = 0; i < len; ++i)
            {
                if (i == index) 
                    continue;
                if (num_contains(d, arr[i]))
                    goto next_num;
            }
            ++ordered[index];
        next_num:
            n /= 10;
        }
    }
}

goto被认为是不好的做法。我不明白他为什么在continue上也这么说。

无论如何-改变继续很容易-只需反转if

        for (int i = 0; i < len; ++i)
        {
            if (i != index) 
            {
                if (num_contains(d, arr[i]))
                    goto next_num;
            }
        }

或者更简单的:

        for (int i = 0; i < len; ++i)
        {
            if (i != index && num_contains(d, arr[i])) 
                    goto next_num;
        }

现在,去掉goto。在本例中,您使用goto来中断循环并跳过++。所以你可以把它改成:

        int i;
        for (i = 0; i < len; ++i)
        {
            if (i != index && num_contains(d, arr[i])) 
               break;
        }
        if (i == len)
             ++ordered[index];
        ...

注意:我是按原样在你的代码上执行这些更改的。没有回顾它是做什么的或者它应该做什么。这只是一般的代码优化方法。

编辑

为了避免使用break,您可以使用if中的条件来停止它。就个人而言,我更喜欢break。它更清楚,这就是它在语言中的存在。

        int i, stop = 0;
        for (i = 0; i < len && !stop; ++i)
        {
            if (i != index && num_contains(d, arr[i])) 
               stop = 1;
        }
        if (i == len) //Or you can use if(!stop)
           ++ordered[index];

这里有一个解决方案,只需要对代码进行最小的更改:

void getrare(int *arr, int *ordered, int len)
{
    for (int index = 0; index < len; ++index)
    {
        int n = arr[index];
        int d = 0;
        while (n)
        {
            d = n % 10;
            int i;      // keep track of loop counter outside the loop
            for (i = 0; i < len; ++i)
            {
                if (i != index && num_contains(d, arr[i]))
                    break;
            }
            // only increment the array if the loop exited before
            // completing (implying the goto would have happened)
            if (i == len)
            {
                ++ordered[index];
            }
            // but always execute this next line of code
            n /= 10;
        }
    }
}

continue在这种特殊情况下是坏的,而goto一般都是坏的。我只给你看了下面的相关部分:

while (n)
{
    d = n % 10;
    for (int i = 0; 
         i < len && !num_contains(d, arr[i]); 
         ++i);
    if(i == len)
      ++ordered[index];
    n /= 10;
}

我不知道你到底在做什么,但我也没有改变你的核心逻辑。

在子函数中拆分有助于消除break;继续goto in循环:

bool does_contain(const int* arr, int len, int d, int ignoredIndex)
{
    for (int i = 0; i < len; ++i) {
        if (i != ignoredIndex && num_contains(d, arr[i])) {
            return true;
        }
    }
    return false;
}
void getrare(const int *arr, int *ordered, int len)
{
    for (int index = 0; index < len; ++index)
    {
        int n = arr[index];
        while (n)
        {
            int d = n % 10;
            if (!does_contain(arr, len, d, index)) {
                ++ordered[index];
            }
            n /= 10;
        }
    }
}