当条件变为假时,为什么我不能退出for循环?

时间:2017-11-25 10:57:20

标签: c arrays for-loop cycle

我希望在用户输入“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");
}

但结束的唯一方法是键入一些字符。

4 个答案:

答案 0 :(得分:3)

您必须了解for循环中的操作顺序才能找到答案:

  1. 执行初始化操作,即i=0
  2. 在进入循环之前检查条件。这是您的第一个问题,因为o[]m[]s[]未初始化。
  3. 执行循环体
  4. 执行
  5. i++
  6. 控件转到第2步
  7. 请注意,步骤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;
        }
    }
    

答案 1 :(得分:2)

您的代码有几个问题:

  • for循环在执行其正文之前检查其条件。在第一轮中,您将检查未初始化的变量。请改用do ... while()循环或初始化数组。
  • 您无法将输入解析为整数并检查双零。如果要执行此操作,则必须将此部分输入解析为字符串。
  • 您应该检查scanf的返回值以检测错误。

答案 2 :(得分:1)

按照目前的说法,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);

答案 3 :(得分:0)

如果您要使用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");
}