为什么当条件为假时我不能退出for循环?
Why can't I exit the for cycle when the condition becomes false?
我希望循环在用户键入“0 00 00”时结束。这是代码:
main()
{
int i, o[128], m[256], s[256];
for(i = 0; o[i] != 0 && m[i] != 00 && s[i] != 00; i++)
scanf("%d %d %d", &o[i], &m[i], &s[i]);
printf("ok\n");
}
但结束它的唯一方法是输入一些字符。
您必须了解 for
循环中的操作顺序才能找出答案:
- 执行初始化操作,即
i=0
- 在进入循环之前检查条件。这是您的第一个问题,因为
o[]
、m[]
和 s[]
未初始化。
- 循环体被执行
i++
执行
- 控制传递到步骤 2
注意第2步的条件总是"ahead"循环体,检查还没有初始化的元素
在这种情况下,最好使用 break
语句从内部结束循环,如下所示:
for (int i = 0 ; i != 128 ; i++) { // Preserve the boundaries of o[128]
scanf("%d %d %d", &o[i], &m[i], &s[i]);
if (o[i] == 0 && m[i] == 0 && s[i] == 0) {
break;
}
}
您的代码有几个问题:
for
循环在 执行其主体之前检查其条件。在第一轮中,您将检查未初始化的变量。请改用 do ... while()
循环或初始化数组。
- 您无法将输入解析为整数并检查双零。如果你想这样做,你必须将这部分输入解析为字符串。
- 您应该检查
scanf
的 return 值以检测错误。
如果您被迫使用 for
循环并依赖其条件来打破它,您可以这样解决这个问题:
int main(void)
{
int o[128 + 1] = {-1}, m[256 + 1] = {-1}, s[256 + 1] = {-1};
for(size_t i = 1; /* Use size_t to index arrays */
i < (128 + 1) && o[i-1] != 0 && m[i-1] != 0 && s[i-1] != 0;
i++) {
scanf("%d %d %d", &o[i], &m[i], &s[i]);
}
puts("ok");
}
请注意,数组位置 0
处的值未被读取,而是固定为 -1
。
如果您的代码依赖于基于 0
的索引,您可以通过以下方式进行欺骗:
int main(void)
{
int oa[128 + 1] = {-1}, ma[256 + 1] = {-1}, sa[256 + 1] = {-1};
int *o = oa + 1, *m = ma + 1, *s = sa + 1;
for(size_t i = 0; /* Use size_t to index arrays */
i < 128 && o[i-1] != 0 && m[i-1] != 0 && s[i-1] != 0;
i++) {
scanf("%d %d %d", &o[i], &m[i], &s[i]);
}
puts("ok");
}
然而,更好的解决方案是:
int main(void)
{
int o[128], m[256], s[256];
{
ssize_t i = -1; /* If ssize_t isn't available use any signed integer wide enough. */
do {
++i;
scanf("%d %d %d", &o[i], &m[i], &s[i]);
} while (i < 128 && o[i] != 0 && m[i] != 0 && s[i]);
}
puts("ok");
}
如当前所写,i
在检查条件之前递增 ,因此每次您只是检查 不确定的值,表现出未定义的行为。
使用 do-while 确保循环至少执行一次,同时让您有更多控制权:
i = -1; // Note the -1 here!
do{
i++;
scanf("%d %d %d", &o[i], &m[i], &s[i]);
} while (o[i] != 0 && m[i] != 0 && s[i] != 0);
我希望循环在用户键入“0 00 00”时结束。这是代码:
main()
{
int i, o[128], m[256], s[256];
for(i = 0; o[i] != 0 && m[i] != 00 && s[i] != 00; i++)
scanf("%d %d %d", &o[i], &m[i], &s[i]);
printf("ok\n");
}
但结束它的唯一方法是输入一些字符。
您必须了解 for
循环中的操作顺序才能找出答案:
- 执行初始化操作,即
i=0
- 在进入循环之前检查条件。这是您的第一个问题,因为
o[]
、m[]
和s[]
未初始化。 - 循环体被执行
i++
执行- 控制传递到步骤 2
注意第2步的条件总是"ahead"循环体,检查还没有初始化的元素
在这种情况下,最好使用 break
语句从内部结束循环,如下所示:
for (int i = 0 ; i != 128 ; i++) { // Preserve the boundaries of o[128]
scanf("%d %d %d", &o[i], &m[i], &s[i]);
if (o[i] == 0 && m[i] == 0 && s[i] == 0) {
break;
}
}
您的代码有几个问题:
for
循环在 执行其主体之前检查其条件。在第一轮中,您将检查未初始化的变量。请改用do ... while()
循环或初始化数组。- 您无法将输入解析为整数并检查双零。如果你想这样做,你必须将这部分输入解析为字符串。
- 您应该检查
scanf
的 return 值以检测错误。
如果您被迫使用 for
循环并依赖其条件来打破它,您可以这样解决这个问题:
int main(void)
{
int o[128 + 1] = {-1}, m[256 + 1] = {-1}, s[256 + 1] = {-1};
for(size_t i = 1; /* Use size_t to index arrays */
i < (128 + 1) && o[i-1] != 0 && m[i-1] != 0 && s[i-1] != 0;
i++) {
scanf("%d %d %d", &o[i], &m[i], &s[i]);
}
puts("ok");
}
请注意,数组位置 0
处的值未被读取,而是固定为 -1
。
如果您的代码依赖于基于 0
的索引,您可以通过以下方式进行欺骗:
int main(void)
{
int oa[128 + 1] = {-1}, ma[256 + 1] = {-1}, sa[256 + 1] = {-1};
int *o = oa + 1, *m = ma + 1, *s = sa + 1;
for(size_t i = 0; /* Use size_t to index arrays */
i < 128 && o[i-1] != 0 && m[i-1] != 0 && s[i-1] != 0;
i++) {
scanf("%d %d %d", &o[i], &m[i], &s[i]);
}
puts("ok");
}
然而,更好的解决方案是:
int main(void)
{
int o[128], m[256], s[256];
{
ssize_t i = -1; /* If ssize_t isn't available use any signed integer wide enough. */
do {
++i;
scanf("%d %d %d", &o[i], &m[i], &s[i]);
} while (i < 128 && o[i] != 0 && m[i] != 0 && s[i]);
}
puts("ok");
}
如当前所写,i
在检查条件之前递增 ,因此每次您只是检查 不确定的值,表现出未定义的行为。
使用 do-while 确保循环至少执行一次,同时让您有更多控制权:
i = -1; // Note the -1 here!
do{
i++;
scanf("%d %d %d", &o[i], &m[i], &s[i]);
} while (o[i] != 0 && m[i] != 0 && s[i] != 0);