2

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

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.

  • 4
    No, unless you count `goto` ;) You could put the loops in a function and simply `return`. – paddy Aug 05 '23 at 07:36
  • 3
    You could set a flag that is tested in both of the `for()` conditions... When flag is set, terminate the inner, then the outer loop. – Fe2O3 Aug 05 '23 at 07:39
  • Following paddy's suggestion: https://ideone.com/TOX6Uh – pmg Aug 05 '23 at 09:09
  • Does this answer your question? [How to break out of nested loops?](https://stackoverflow.com/questions/9695902/how-to-break-out-of-nested-loops) – wovano Aug 05 '23 at 12:12
  • https://stackoverflow.com/questions/9695902/how-to-break-out-of-nested-loops – Paolo Marrone Aug 05 '23 at 23:38
  • @PaoloMarrone, I already posted that link :-) Once you have enough [reputation](https://stackoverflow.com/help/privileges) you can flag or close-vote the question as duplicate. – wovano Aug 06 '23 at 07:14

4 Answers4

1

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 < 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 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 < 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);
        }
    }
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • 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. – Alexander Gromov Aug 05 '23 at 09:30
  • You can use `goto` to break from the third inner loop to after the end of the second loop, but using a flag is probably more appropriate. C does not have labelled loops you can `break` from, it has labelled statements you can jump to with `goto`. Adding labelled loops in C23 would have been logical, but C++ does not have them either and it might have caused even more confusion with `goto` already poor semantics. So no there is no precise equivalent to java's labelled loops. – chqrlie Aug 05 '23 at 09:46
1

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 "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


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(...);
    }
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
0

Firstly some remarks relative to your code. The both statements

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

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

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

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 < 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 );
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
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)
August Karlstrom
  • 10,773
  • 7
  • 38
  • 60