Java, бесконечный цикл while, приращение

в следующем примере программы на Java я получаю бесконечный цикл, и я не могу понять, почему:

public class Time {

    public static int next(int v) {
        return v++;
    }

    public static void main(String[] args) {

        int[] z = {3, 2, 1, 0};

        int i = 1;

        while(i < 4) {
            System.out.println(z[i]/z[i]);
            i = next(i);
        }
    }
}

В цикле while вызывается метод next(), и значение i должно каждый раз увеличиваться на 1: next() должно возвращать i++, а значение i в цикле while должно увеличиваться на единицу.

Почему может быть причиной бесконечного цикла? Спасибо.


person user42155    schedule 31.01.2009    source источник
comment
следите за делением на ноль, когда i = 3.   -  person Amarghosh    schedule 15.09.2009


Ответы (7)


Вы используете пост-инкремент. Это должно работать:

public static int next(int v) {
        return v+1; //or ++v
    }

так что в основном ваша следующая функция в вашем примере возвращает тот же номер, а не увеличенный.

person empi    schedule 31.01.2009
comment
i++ — постинкрементный, ++i — преинкрементный. он / она уже использует постинкремент, что является причиной ошибки. - person Barış Akkurt; 22.01.2019

Определение для v++:

Return the current value of v then add one to v

В вашем случае v — это параметр метода, который является копией переменной i в main, поэтому метод просто возвращает то же значение, которое было ему передано. Увеличенное значение в v никогда не используется.

Вы могли бы использовать ++v. Определение этого:

Add one to v, then return the new value
person Adrian Pronk    schedule 31.01.2009
comment
Для бонусных баллов: каково значение i после выполнения i = i++;? - person Michael Myers; 05.02.2009
comment
Внезапно я считаю, что официальный ответ не определен. Но я не собираюсь торопиться и экспериментировать. - person Adrian Pronk; 06.02.2009
comment
только что протестировано и не изменилось (в actionscript). - person Amarghosh; 15.09.2009

Разница здесь в постфиксных и префиксных операторах.

Например:

int a = 1;
int b = a++; // sets b to to 1 THEN increments a.

// a now equals 2.

int c = ++a; // increments a THEN stores the value in c, c = 3.

вызов метода, который возвращает int++, не сделает того, что вы ожидаете. Это не то же самое, что иметь это:

while (expression) {
// code...
intValue++;
}

потому что в приведенном выше блоке кода приращение не передается в отдельную переменную, и полное приращение значения произойдет до выхода из блока кода, формы постфикса или префикса.

public static int someMethod(int n) {
return n++;  
}

тогда как кодовый блок выше вернет n, а затем увеличит его позже. Но поскольку ваш код будет продолжать присваивать одно и то же значение int n, он будет продолжать возвращать одно и то же значение, поскольку он увеличивает не ваше значение, а переменную, локальную для этого метода, n. Однако каждый раз, когда вы передаете новое значение, n сбрасывается и возвращает одно и то же, что приводит к бесконечному циклу.

person John T    schedule 31.01.2009

Есть ли причина, по которой вы не используете более идиоматичное и легко читаемое:

for(int i = 0; i < 4; i++){
    System.out.println(z[i]/z[i]);
}

... или даже:

for(int x : z){
    System.out.println(x / x);
}

... ?

person Aaron Maenpaa    schedule 31.01.2009
comment
for(int x : z) {...} не является законным для Java. - person Darron; 31.01.2009
comment
@Darron, да, это улучшенный цикл for, представленный в Java 5. - person Dan Dyer; 31.01.2009

public static int next(int v) {
        return ++v;
}

Не забывайте, что массивы начинаются с нулевого индекса в Java, а деление на ноль вызывает исключение.

person raupach    schedule 31.01.2009

Вы должны использовать

public static int next(int v) {
        return v + 1;
}

Использование v++ неверно, так как возвращаемое значение является исходным значением v до увеличения.

Кроме того, использование ++v или v++ в операторе return — плохой стиль, потому что ++ имеет побочный эффект модификации v, а в выражениях не должно быть никаких побочных эффектов. Побочные эффекты следует указывать только в отдельных утверждениях, чтобы избежать путаницы и неопределенного порядка оценки.

person starblue    schedule 31.01.2009

post increment работает, это точно, но вы получите исключение из-за использования значения «0» в массиве. логически 0/0 невозможен, он бесконечен, поэтому, кроме случаев, избегайте деления на значение «0»

person Community    schedule 15.09.2009