英文:
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<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.
答案1
得分: 1
C语言中的逻辑不同:不是从一个外部标记的循环中跳出,而是可以使用前向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);
}
}
英文:
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);
}
}
答案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()//#2
和 for()//#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 "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;
}
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("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 );
}
答案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 <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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论