Как здесь работает область видимости переменной java? - PullRequest
1 голос
/ 17 апреля 2020

Я пробовал примерную формулировку проблемы и правильный код, для которого что-то вроде этого -

import java.util.Scanner;

public class Sample {
    private static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        int m = 5, n = 5;
        int dist = 0;
        for(int i = 0; i < m; ++i) {
            for(int j = 0; j < n; ++j) {
                int value = scanner.nextInt();
                if(value == 1) {
                    dist = Math.abs(i - 2) + Math.abs(j - 2);
                }
            }
            scanner.nextLine();
        }
        System.out.println(dist);
    }
}

Это отлично работает, давая правильный ответ. Но когда я пишу код -

import java.util.Scanner;

public class Sample {
    private static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        int m = 5, n = 5;
        int i = 0, j = 0;
        int dist = 0;
        for(; i < m; ++i) {
            for(; j < n; ++j) {
                int value = scanner.nextInt();
                if(value == 1) {
                    dist = Math.abs(i - 2) + Math.abs(j - 2);
                }
            }
            scanner.nextLine();
        }
        System.out.println(dist);
    }
}

Ответ всегда равен 0. Для примера ввода -

0 0 0 0 0
0 0 0 0 1
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

Правильный ответ - 3, и я получаю 3 при выполнении 1-го куска кода. Но не во время выполнения второго фрагмента кода.

Ответы [ 3 ]

1 голос
/ 17 апреля 2020

Другим подходом может быть следующее для сброса переменной j, как упоминалось ранее

public class Sample {

    private static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        int m = 5, n = 5;
        int i = 0, j = 0;
        int dist = 0;
        for(; i < m; ++i, j = 0) {
            for(; j < n; ++j) {
                int value = scanner.nextInt();
                if(value == 1) {
                    dist = Math.abs(i - 2) + Math.abs(j - 2);
                }
            }
            scanner.nextLine();
        }
        System.out.println(dist);
    }
}
0 голосов
/ 17 апреля 2020

В первом фрагменте кода переменная j сбрасывается в 0 каждый раз, когда код выходит и перезапускает этот внутренний l oop. Во втором фрагменте кода этого не происходит. Шаг за шагом посмотрим, что хранят переменные, может быть полезно. Я добавил следующую строку во внутреннюю l oop и закомментировал пользовательский раздел ввода для целей отладки:

System.out.println("( " + i + " " + j + ")");

В первом примере это печатает:

( 0 0)
( 0 1)
( 0 2)
( 0 3)
( 0 4)
( 1 0)
( 1 1)
( 1 2)
( 1 3)
( 1 4)
( 2 0)
( 2 1)
( 2 2)
( 2 3)
( 2 4)
( 3 0)
( 3 1)
( 3 2)
( 3 3)
( 3 4)
( 4 0)
( 4 1)
( 4 2)
( 4 3)
( 4 4)

Однако для второго примера он печатает:

( 0 0)
( 0 1)
( 0 2)
( 0 3)
( 0 4)

По существу, во втором примере j не сбрасывается для каждой итерации внешнего l oop. Если вы добавите больше операторов печати в других местах, например, внутри внешнего l oop, но не во внутреннем, область видимости станет еще более ясной. Важно отметить, что внешний l oop все еще выполняется 5 раз, у нас просто нет никаких доказательств этого, поскольку оператор print становится недоступным после первого прохода через внутренний l oop.

0 голосов
/ 17 апреля 2020

Проблема в том, что переменная j не сбрасывается в 0.

Правильный код будет:

import java.util.Scanner;

public class Sample {
    private static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        int m = 5, n = 5;
        int i = 0;
        int dist = 0;
        for(; i < m; ++i) {
            int j = 0; // <== this line was missing
            for(; j < n; ++j) {
                int value = scanner.nextInt();
                if(value == 1) {
                    dist = Math.abs(i - 2) + Math.abs(j - 2);
                }
            }
            scanner.nextLine();
        }
        System.out.println(dist);
    }
}

Если вы не знаете, посмотрите, как оператор for работает в https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html

...