2015-10-03 2 views
1

У меня есть цикл for, и я инициализирую переменные внутри этого цикла. После этого мне нужно манипулировать этими переменными, но компилятор говорит, что переменные не инициализируются.Инициализация переменных внутри цикла

public class Solution { 
    static void displayPathtoPrincess(int n, String[] grid) { 
     String[][] visual = new String[n][n]; 
     for (int i = 0; i < n; i++) { 
      char[] myGrid = grid[i].toCharArray(); 
      for (int j = 0; j < n; j++) { 
       visual[i][j] = myGrid[j] + ""; 
      } 
     } 

     int pX; 
     int pY; 
     int bX; 
     int bY; 
     // rescue the princess 
     for (int i = 0; i < n; i++) { 
      for (int j = 0; j < n; j++) { 
       if (visual[i][j].equals("p")) { 
        pX = j; 
        pY = i; 
       } 
       if (visual[i][j].equals("m")) { 
        bX = j; 
        bY = i; 
       } 
      } 
     } 
     System.out.println(pY + ""); 
     System.out.println(pX + ""); 
    } 

    public static void main(String[] args) { 
     Scanner in = new Scanner(System.in); 
     int m; 
     m = in.nextInt(); 
     String grid[] = new String[m]; 
     for (int i = 0; i < m; i++) { 
      grid[i] = in.next(); 
     } 

     displayPathtoPrincess(m, grid); 
    } 
} 

if условие true в какой-то момент. Фактически, если я перемещаю операторы печати внутри if, он работает.
Как решить эту проблему?

+0

Вы уверены, что первое условие оператора 'if' истинно в какой-то момент вашего цикла? Если это не так, 'pX' и' pY' не получат значения. – Jason

+0

абсолютно уверен. Если я напечатаю значение внутри цикла, он будет работать. – Manfredi

ответ

0

Ниже отрывок из JLS §16 (Definite Assignment)

Для каждого доступа к локальной переменной или пустой конечного поля х, х должно быть определенно назначенную перед въездом или ошибка компиляции.

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

В вас случае, если n является 0, то ваш for (int i = 0; i < n; i++) { цикл никогда не будет работать, так что компилятор не может быть уверен, что в данный момент System.out.println(pY + "");, pY бы в инициализированном состоянии, так жалуется.

Для решения: Перед использованием/чтением вы должны инициализировать локальную переменную.

Вы можете печатать pX и pY, потому что компилятор уверен в этой точке, что значения будут инициализируются, однако попробовать ниже и даже в вашем IF блока вы увидите, что есть ошибка компиляции, потому что вы пытаетесь читать локальные переменные до их инициализации, поэтому компилятор жалуется.

Итак, нижняя строка - make компилятор полагает, что локальная переменная была бы инициализирована в этой точке, поэтому перед их использованием инициализируйте локальные переменные.

if (visual[i][j].equals("p")) { 
        System.out.println(pY + ""); //Compilation error because compiler is not sure if LV would be in initialized state. 
        pX = j; 
        pY = i; 
        System.out.println(pY + ""); //Happy compiler becuse it is sure that LV are just initialized. 
       } 
+0

Это нормально, но если я инициализирую их 0, то их значение будет равно 0 даже после цикла. – Manfredi

+0

Даже если вы не инициализируете их, тогда будет значение для мусора, не так ли? У вас проблемы, потому что вы пытаетесь напечатать 'pX' и' pY', используя 'System.out.println (pX +" ");', если вы их не распечатываете, вы сможете компилятор. Таким образом, имеет смысл читать значение, когда на самом деле будет какое-то значение. В конце цикла FOR, если нет значения, тогда нет точки печати. Если для отладки вы хотите узнать, были ли инициализированы 'pX' и' pY', используйте логическое значение для проверки (изначально FALSE, make true в IF и затем чтение в конце). – hagrawal

+0

Мне нужно сделать некоторые манипуляции. Я не могу получить к ним доступ за пределами цикла? Как я мог это решить? – Manfredi

1

Если вы хотите, чтобы инициализировать переменные в условиях, то вам необходимо установить их значения по умолчанию:

int pX = 0; 
int pY = 0; 
int bX = 0; 
int bY = 0; 

Таким образом, ваш компилятор не будет возвращать вопрос инициализации больше.

EDIT

Я сделал некоторые изменения, так как я не мог сделать код работы (отлиты из строки в целое, массив полукокса вопроса инициализации и т.д.). Не могли бы вы попробовать это пожалуйста:

public class Solution { 
static void displayPathtoPrincess(String grid) { 
    int n = grid.length(); 
    String[][] visual = new String[n][n]; 
    for (int i = 0; i < n; i++) { 
     for (int j = 0; j < n; j++) { 
      visual[i][j] = String.valueOf(grid.charAt(j)); 
     } 
    } 

    int pX = 0; 
    int pY = 0; 
    int bX; 
    int bY; 
    // rescue the princess 
    for (int i = 0; i < n; i++) { 
     for (int j = 0; j < n; j++) { 
      if (visual[i][j].equals("p")) { 
       pX = j; 
       pY = i; 
      } 
      if (visual[i][j].equals("m")) { 
       bX = j; 
       bY = i; 
      } 
     } 
    } 
    System.out.println(pY + ""); 
    System.out.println(pX + ""); 
} 

public static void main(String[] args) { 
    Scanner in = new Scanner(System.in); 
    String grid = in.next(); 

    displayPathtoPrincess(grid); 
} 

Это, вероятно, не то, что вы хотите сделать, но у меня нет никаких проблем со значениями переменных инициализируется в условиях.

+0

Я попробовал. Если я это сделаю, то значение переменной после цикла равно 0. – Manfredi

+0

вы можете показать нам, как ваш визуальный [i] [j] установлен на его значение? Ваше условие просто возвращает false, а ваши переменные сохраняют свои значения по умолчанию. –

+0

Как я уже сказал, в какой-то момент верно. И я могу напечатать значение внутри If. – Manfredi

0

вы могли бы попробовать это

class Demo 
{ 
static int pX; 
static int pY; 
static int bX; 
static int bY; 

public static void main(String a) 
{ 
for (int i = 0; i < n; i++) { 
    for(int j = 0; j < n; j++) { 
     if (visual[i][j].equals("p")) { 
      pX = j; 
      pY = i; 
     } 
     if (visual[i][j].equals("m")) { 
      bX = j; 
      bY = i; 
     } 
    } 
} 
System.out.println(pY + ""); 
System.out.println(pX + ""); 
} 

} 
+1

это может сработать, но статические ints кажутся совершенно неуместными для того, что представляется временными данными. лучше просто инициализировать значения int до 0 – David

+0

Здесь нарушаются правила области. Если переменные используются только внутри блока, они должны быть помещены внутри блока. – nicomp

0

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

Он не знает, будет ли выполняться любая из ветвей if, когда ваша программа будет выполнена.

Это хорошая практика, чтобы всегда давать переменным исходное значение, чтобы избежать подобных проблем.

+0

Это нормально, но если я инициализирую их 0, то их значение будет равно 0 даже после цикла. – Manfredi

Смежные вопросы