Почему следующие фрагменты (один, использующий "while", другой, использующий "for"), имеют различное поведение? - PullRequest
0 голосов
/ 05 февраля 2010

Я пробовал некоторые базовые упражнения с использованием петель.

Может кто-нибудь сказать мне, почему следующие фрагменты имеют разные выходы?


В то время как петля

while (i<3)
{
    while(j<3)
    {
        printf("(%d %d) ",i,j);
        j++;
    }
    i++;
}

Выход

(0 0) (0 1) (0 2)

для цикла

for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
            printf("(%d %d) ",i,j);
    }

выход

(0 0) (0 1) (0 2) (1 0) (1 1) (1 2) (2 0) (2 1) (2 2) 

Разве они не должны иметь одинаковый выход?

Ответы [ 9 ]

15 голосов
/ 05 февраля 2010

Попробуйте:

while (i<3)
{
    j = 0;
    while(j<3)
    {
        printf("(%d %d) ",i,j);
        j++;
    }
    i++;
}

В вашем коде все просто: первый цикл i = 0, j = 0, 1, 2, 3, второй i = 1, j = 3 ...

9 голосов
/ 05 февраля 2010

Вы не переинициализируете переменную до запуска цикла while, как в цикле for. Попробуйте это:

i = 0;
while (i<3)
{
    j = 0;
    while(j<3)
    {
        printf("(%d %d) ",i,j);
        j++;
    }
    i++;
}
5 голосов
/ 05 февраля 2010

Вы никогда не будете повторно устанавливать переменные в цикле while.

2 голосов
/ 05 февраля 2010

Может кто-нибудь сказать мне, почему следующие фрагменты имеют разные выходы?

Да, они не эквивалентны. Чтобы сделать два фрагмента кода эквивалентными, вам нужно инициализировать i = 0 и особенно j = 0 внутри цикла while следующим образом:

i = 0;
while (i < 3) { 
    j = 0;
    while(j < 3) { 
        printf("(%d %d)", i, j); 
        j++; 
    } 
    i++; 
} 

Помните, что

for(init-statement condition; expression) {
    statement
}

переводится как

init-statement
while(condition) {
    statement
    expression
}

В частности,

for(j = 0; j < 3; j++)   
    printf("(%d %d)", i, j);   

переводится как

j = 0;
while(j < 3) {
    printf("(%d %d)", i, j);
    j++;
}

Таким образом, вам не хватает самой ключевой инициализации j = 0 перед входом во внутренний цикл while, а также инициализации i = 0 перед входом во внешний цикл while.

Итак, чтобы обернуть все это, перевод

for(i = 0; i < 3; i++) { 
    for(j = 0; j < 3 ; j++) 
        printf("(%d %d)", i, j); 
}

is (первый проход)

i = 0;
while(i < 3) {
    for(j = 0; j < 3; j++)
        printf("(%d %d)", i, j);
    i++;
} 

и наконец

i = 0;
while(i < 3) {
    j = 0;
    while(j < 3) {
        printf("(%d %d)", i, j);
        j++;
    }
    i++;
}
2 голосов
/ 05 февраля 2010

Внутренний цикл while выполняется только один раз, потому что ваша переменная j равна 3 и никогда не сбрасывается.

1 голос
/ 14 марта 2012

Короче говоря, вы не сбросили переменную "j", когда она достигает 3 после первой итерации "i".Всегда инициализируйте переменную while, прежде чем использовать их.

0 голосов
/ 05 февраля 2010

Вот почему вы объявляете свои переменные в той области, в которой они должны существовать. Например, они должны возвращать те же значения, которые вы получили бы от for.

while (i<3)
{
    int j;
    while(j<3)
    {
        printf("(%d %d) ",i,j);
        j++;
    }
    i++;
}

Почему? Потому что j воссоздается для каждого цикла внешнего while.

0 голосов
/ 05 февраля 2010

Как говорили другие, вы не сбросили переменную j. В общем могу сказать

s1;
while(condition){
    s0;
    s2;
}

... не равно ...

for(s1;condition;s2){
    s0;
}

... потому что если s0 содержит continue, то s2 не выполняется в первом случае, а выполняется во втором.

Во-вторых, объявления переменных в s1 будут ограничены циклом во втором случае. Раньше это было желательно, но иногда нет. В этом случае вы можете сделать объявление перед циклом.

0 голосов
/ 05 февраля 2010

в операторе while ваше значение для j остается равным 3 и больше не выполняется.он сбрасывается в цикле for.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...