2015-09-30 26 views
1

我有以下的代碼中調用代碼#1重新排列變量後爲什麼輸出不同?

Scanner keyboard = new Scanner(System.in); 
String s = keyboard.nextLine(); 
int x = keyboard.nextInt(); 
double y = keyboard.nextDouble(); 
System.out.println("String: "+s); 
System.out.println("Double: "+y); 
System.out.println("Int: "+x); 

如果我進入

Hello World 
12.1 
12 

輸出將是

String: Hello World 
Double: 12.1 
Int: 12 

不過,如果我重新安排我的代碼,調用它代碼#2,如

Scanner keyboard = new Scanner(System.in); 
int x = keyboard.nextInt(); 
double y = keyboard.nextDouble(); 
String s = keyboard.nextLine(); 
System.out.println("String: "+s); 
System.out.println("Double: "+y); 
System.out.println("Int: "+x); 

和我輸入

12 
12.1 

編譯器跳過字符串輸入和輸出

String: 
Double: 12.1 
Int: 12 

這是奇數我。我被教導編譯器總是從上到下閱讀。我想象編譯器讀取代碼#2爲

int x = keyboard.nextInt(); 

首先等待用戶輸入一個整數,以便它可以將其分配給x。然後讀取

double y = keyboard.nextDouble(); 

等待用戶輸入一個雙因此它可以被分配給y。然後它終於讀取

String s = keyboard.nextLine(); 

並等待用戶輸入一個字符串,因此它可以將其分配給s。實際上,對我來說,這是編譯器如何讀取代碼#1並輸出所需的。這似乎是一個微妙的差異,重新排列變量,但爲什麼產出如此不同?

+0

您是否更改首先要求的值的順序,並且您希望它以相同的方式工作?我在這裏丟失了一些東西...... –

+0

您也在使用_runtiime_來解析源代碼並生成一個二進制文件的_compiler_,它執行代碼(請注意,「runtime」可能是物理cpu,如一個C程序,但對於Java而言,它是JVM)。如果我編寫了一個從頭到尾讀源文件的編譯器,它將(應該)對__ execution_沒有任何影響。 –

回答

4

這不是編譯器。這不是變量聲明的順序。這是您從輸入流中讀取的順序。

在第二種情況下,您讀取了int,double和line。這正是它所做的。

int x = keyboard.nextInt();  // Reads "12" 
double y = keyboard.nextDouble(); // Reads "12.1" 
String s = keyboard.nextLine(); // Reads the remainder of the "12.1" line. 

作爲一個方面的問題,請注意,「下一行」中輸入的是在「12.1」行的其餘部分「12.1」被讀取後。這在「Scanner is skipping nextLine() after using next(), nextInt() or other nextFoo() methods」問題中有更詳細的描述。

1

我正在寫這個很快很抱歉,如果我有錯誤或不清楚。請讓我知道。

這裏的問題是掃描儀,而不是編譯器。掃描儀按照您要求的方式讀取它有權訪問的文本。

當您使用nextLine()方法時,您要求掃描儀從光標的當前位置讀取到行的末尾,或者如果沒有當前文本被引用,則獲取新的一行文本。

從鍵盤獲取新文本,因爲 Scanner對象中當前沒有文本。然後閱讀從 鍵盤收到的全部文本,並將其作爲字符串返回給調用者。由於讀取了整行 ,因此如果您調用 新的下一個***()方法,則掃描器會假定您不再需要它。

String s = keyboard.nextLine(); 

擺脫鍵盤新的文本,因爲沒有在 掃描器讀取object.Then是可解析從文本一個int 從鍵盤上接收到並返回一個int第一個文本目前文本到 的調用者。問題是,這基本上是掃描儀在輸入文本「12.1 \ n」時看到的 。正如你所知道的那樣,「\ n」是 返回的符號(就像按回車鍵來換新行一樣)。這意味着您的 掃描儀光標現在位於int you 進入後的位置,但仍然有「\ n」可供讀取。

例: 「12.1 * \ n」 //將*再次表示光標

int num = keyboard.nextInt();

得到新的文本[/代碼]的位置,所以,當我們現在 調用nextLine(),它將讀取當前行的其餘部分。不是 需要用戶的任何輸入,因爲掃描儀仍然有文字 要讀取。

s = keyboard.nextLine();

對於一個初學者,只需後的各nextInt /雙人/等添加keyboard.nextLine()來完成讀線路。我並不是說這是做事的「正確」方式,但對於初學者來說,這是完美的。

String s = keyboard.nextLine(); 
int num = keyboard.nextInt(); 
//read to end of Scanner object's text to "reset" it 
keyboard.nextLine(); 
//get text normally 
s = keyboard.nextLine();