繁体   English   中英

当条件变为假时,为什么不能退出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循环中的操作顺序才能找出答案:

  1. 执行初始化操作,即i=0
  2. 在进入循环之前检查条件。 这是您的第一个问题,因为o[]m[]s[]未初始化。
  3. 循环体执行
  4. i++执行
  5. 控件传递到步骤2

请注意,步骤2中的条件始终在循环主体“前面”,检查尚未初始化的元素。

在这种情况下,最好使用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的返回值以检测错误。

正如目前所写的那样, 检查条件之前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);

如果您习惯使用for -loop并依靠其条件来打破它,则可以这样解决此问题:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM