如何在C中退出外部循环(不使用++)?

huangapple go评论109阅读模式
英文:

How to exit an outer loop in C (without ++)?

问题

在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; //在此处,或使用 "continue outer;";
      }
  System.out.println("value " + value + " not found");
}

在C中是否有类似的构造(不使用++)?

问题是,我的问题针对的点略有不同,上面我提供了一个简单的示例。如果我有3个循环(或更多)。而在第3个循环中,我需要立即中断第2个循环,但不中断第1个循环。我能在循环内部使用goto吗?

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

感谢关于如何创建标志的提示。我意识到可以用这种方式做,但我想知道在C中是否可以像在Java中一样做到这一点,以了解C语言的能力。程序只是一个示例。

英文:

In Java, it is possible to escape from an outer loop using such a construct:

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

Are there any similar constructs in C (without ++)?

The thing is that my question was addressing a slightly different point, above I gave a simple example.
What if I have 3 cycles (or more). And being in cycle 3, I need to interrupt cycle 2 at once, but without interrupting cycle 1.
Can I write goto inside the loop?

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

Thanks, for the tips on how to create flags. I realize it can be done that way, but I was wondering if it is possible to do the same in C as in Java. To understand the capabilities of the C language.
The program is just as an example.

答案1

得分: 1

C语言中的逻辑不同:不是从一个外部标记的循环中跳出,而是可以使用前向goto,并在循环结束后放置标签:

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

    for (int i = 0; i &lt; n; i++) {
        for (int j = 0; j &lt; 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 &lt; n; i++) {
            for (j = 0; j &lt; 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);
        }
    }
英文:

The logic in C is different: instead of breaking from an outer labelled loop, you can use a forward goto and place the label after the end of the loop:

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

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

goto has always been part of the C language, breaking from outer loops is a typical use that is not a problem, jumping to common exit paths in case of failure is another fine use of goto, but programs with too many goto statement, especially jumping backwards are hard to understand and even harder to debug so in order to limit usage to breaking from outer loops, labelled loops were introduced in java, javascript and other languages and goto is not available there.

Note however that it is rather easy to avoid labels with an extra variable, and it makes the logic of the code more obvious:

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

答案2

得分: 1

这样的代码片段通常放在一个函数中,当找到所需的值时,您可以直接使用 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};            // 一个“未找到”的位置
    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}; // 分配找到的位置
                return pos;                    // 然后返回它
            }
        }
    }
    return pos;
}

演示


在您添加的代码片段中:

for()//#1
    for()//#2
        for()//#3
            {
                  // 继续 for()#1
            }

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

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

void foo(...) {
    for(...) { //#1
        bar(...);
    }
}
英文:

Such a code snippet is usually placed in a function and you can then just return when the value you search for is found.

Example:

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 &quot;not found&quot; position
    for (size_t i = 0; i &lt; rows; ++i) {
        for (size_t j = 0; j &lt; cols; ++j) {
            if (matrix[i][j] == value) {
                pos = (struct position){i, j}; // assign the found position
                return pos;                    // and return it
            }
        }
    }
    return pos;
}

Demo


In your added snippet:

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

you could put for()//#2 and for()//#3 in a function:

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

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

答案3

得分: 0

以下是您要翻译的代码部分:

首先关于您的代码的一些备注这两个语句

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

希望这有助于您的理解。

英文:

Firstly some remarks relative to your code. The both statements

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

should be placed outside the for loops. The loops should do only one thing: to determine whether an element equal to value is present in matrix.

A simple way is to add one more condition in the for loops. For example

size_t row = 0, col = 0;
int found = 0;
for ( size_t i = 0; !found &amp;&amp; i &lt; n; i++ )
{
for ( size_t j = 0; !found &amp;&amp; j &lt; m; j++ )
{
if ( ( found = matrix[i][j] == value ) )
{
row = i;
col = j;
}
}
}
if ( found )
{ 
printf( &quot;value %d found in cell ( %zu, %zu )\n&quot;, value, row, col );
}
else
{
printf( &quot;value %d not found\n&quot;, value );
}

Alternatively instead of the inner for loop you could use while loop. For example

size_t row = 0, col = 0;
int found = 0;
for ( size_t i = 0; !found &amp;&amp; i &lt; n; i++ )
{
size_t j = 0;
while ( j != m &amp;&amp; matrix[i][j] != value ) ++j;
if ( ( found = j != m ) )
{
row = i;
col = j;
}
}
if ( found )
{ 
printf( &quot;value %d found in cell ( %zu, %zu )\n&quot;, value, row, col );
}
else
{
printf( &quot;value %d not found\n&quot;, value );
}

And at last you could use only one loop provided that the expression n * m does not result in overflow.

size_t i = 0;
while ( i &lt; m * n &amp;&amp; matrix[i / m][i % m] != value ) ++i;
if ( i != n * m )
{ 
printf( &quot;value %d found in cell ( %zu, %zu )\n&quot;, value, i /  m, i % m );
}
else
{
printf( &quot;value %d not found\n&quot;, value );
}

答案4

得分: 0

I think the cleanest solution is to use pure structured programming (i.e. no break statements):

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

Output:

value 8 found in cell (2, 1)
英文:

I think the cleanest solution is to use pure structured programming (i.e. no break statements):

#include &lt;stdio.h&gt;
#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 &amp;&amp; (i &lt; LEN(matrix)) ; i++) {
for (j = 0; ! found &amp;&amp; (j &lt; LEN(matrix[i])); j++) {
if (matrix[i][j] == value) {
found = 1;
row = i;
col = j;
}
}
}
if (found) {
printf(&quot;value %d found in cell (%d, %d)\n&quot;,  value, row, col);
} else {
printf(&quot;value %d not found\n&quot;, value);
}
return 0;
}

Output:

value 8 found in cell (2, 1)

huangapple
  • 本文由 发表于 2023年8月5日 15:34:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/76840589.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定