如何在C中退出外部循环(没有++)?

soat7uwm  于 2023-10-16  发布在  其他
关注(0)|答案(4)|浏览(96)

在Java中,可以使用这样的构造来从外部循环中转义:

int[][] matrix;
int value;
...
outer: {
  for(int i=0; i<n; i++)
    for (int j=0; j<m; j++)
      if (matrix[i][j] == value)
      {
        System.out.println("value " + value + " found in cell (" + i + "," + j + ")");
        break outer; //HERE, or "continue outer;"
      }
  System.out.println("value " + value + " not found");
}

C中是否有类似的结构(没有++)?
问题是,我的问题是解决一个稍微不同的点,上面我给了一个简单的例子。如果我有3个周期(或更多)。在周期3中,我需要立即中断周期2,但不中断周期1。我可以在循环中写后藤吗?

for()//#1
    for()//#2
        for()//#3
            {
                  // continue for()#1
            }

感谢您提供有关如何创建标志的提示。我意识到可以这样做,但我想知道是否有可能在C中像在Java中一样做同样的事情。了解C语言的功能。该程序只是一个例子。

zvms9eto

zvms9eto1#

C语言的逻辑是不同的:你可以使用一个forward goto,并将标签放在循环的末尾,而不是从外部的标签循环中断开:

int matrix[n][m];
    int value;
    ...

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (matrix[i][j] == value) {
                printf("value %d found in cell (%d, %d)\n", value, i, j);
                goto outer;
            }
        }
    }
    printf("value %d not found\n", value);
outer:
    ;     // there must be a statement after a label

goto一直是C语言的一部分,从外部循环中断是一个典型的使用,这不是一个问题,在失败的情况下跳转到公共退出路径是goto的另一个很好的使用,但是有太多goto语句的程序,特别是向后跳转很难理解,甚至更难调试,所以为了限制使用从外部循环中断,在Java、JavaScript和其他语言中引入了带标签的循环,而goto在这些语言中不可用。
但是请注意,使用额外的变量来避免标签是相当容易的,并且它使代码的逻辑更加明显:

int matrix[n][m];
    int value;
    ...
    {
        int i, j, found = 0;
        for (i = 0; i < n; i++) {
            for (j = 0; j < m; j++) {
                if (matrix[i][j] == value) {
                    found = 1;
                    break;
                }
            }
            if (found)
                break;
        }
        if (found) {
            printf("value %d found in cell (%d, %d)\n", value, i, j);
        } else {
            printf("value %d not found\n", value);
        }
    }
owfi6suc

owfi6suc2#

这样的代码片段通常放在一个函数中,然后当找到您搜索的值时,您可以只使用return
范例:

struct position {
    size_t row;
    size_t col;
};

struct position find_element(size_t rows, size_t cols, int matrix[rows][cols],
                             int value) {
    struct position pos = {-1, -1};            // a "not found" position
    for (size_t i = 0; i < rows; ++i) {
        for (size_t j = 0; j < cols; ++j) {
            if (matrix[i][j] == value) {
                pos = (struct position){i, j}; // assign the found position
                return pos;                    // and return it
            }
        }
    }
    return pos;
}

Demo
在添加的代码段中:

for()//#1
    for()//#2
        for()//#3
            {
                  // continue for()#1
            }

你可以把for()//#2for()//#3放在一个函数中:

static void bar(...) {
    for(...) {     // #2
        for(...) { // #3
            if (some_condition) return;
        }
    }
}

void foo(...) {
    for(...) { //#1
        bar(...);
    }
}
cvxl0en2

cvxl0en23#

首先是一些与你的代码相关的评论。这两个声明

System.out.println("value " + value + " found in cell (" + i + "," + j + ")");
System.out.println("value " + value + " not found");

应该放在for循环之外。循环应该只做一件事:以确定在matrix中是否存在等于value的元素。
一个简单的方法是在for循环中再添加一个条件。例如

size_t row = 0, col = 0;
int found = 0;
 
for ( size_t i = 0; !found && i < n; i++ )
{
    for ( size_t j = 0; !found && j < m; j++ )
    {
        if ( ( found = matrix[i][j] == value ) )
        {
            row = i;
            col = j;
        }
    }
}

if ( found )
{ 
    printf( "value %d found in cell ( %zu, %zu )\n", value, row, col );
}
else
{
    printf( "value %d not found\n", value );
}

或者,可以使用while循环代替内部的for循环。例如

size_t row = 0, col = 0;
int found = 0;
 
for ( size_t i = 0; !found && i < n; i++ )
{
    size_t j = 0;

    while ( j != m && matrix[i][j] != value ) ++j;

    if ( ( found = j != m ) )
    {
        row = i;
        col = j;
    }
}

if ( found )
{ 
    printf( "value %d found in cell ( %zu, %zu )\n", value, row, col );
}
else
{
    printf( "value %d not found\n", value );
}

最后,只要表达式n * m不会导致溢出,就可以只使用一个循环。

size_t i = 0;

while ( i < m * n && matrix[i / m][i % m] != value ) ++i;

if ( i != n * m )
{ 
    printf( "value %d found in cell ( %zu, %zu )\n", value, i /  m, i % m );
}
else
{
    printf( "value %d not found\n", value );
}
xxls0lw8

xxls0lw84#

我认为最干净的解决方案是使用纯结构化编程(即。无break语句):

#include <stdio.h>

#define LEN(array) ((int) (sizeof (array) / sizeof (array)[0]))

int matrix[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

int main(void)
{
    int i, j, row, col, found, value;

    value = 8;

    found = 0;
    for (i = 0; ! found && (i < LEN(matrix)) ; i++) {
        for (j = 0; ! found && (j < LEN(matrix[i])); j++) {
            if (matrix[i][j] == value) {
                found = 1;
                row = i;
                col = j;
            }
        }
    }
    if (found) {
        printf("value %d found in cell (%d, %d)\n",  value, row, col);
    } else {
        printf("value %d not found\n", value);
    }

    return 0;
}

输出量:

value 8 found in cell (2, 1)

相关问题