
【環境】
java version "1.6.0_31"
Java(TM) SE Runtime Environment (build 1.6.0_31-b05)
Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01, mixed mode)
----------------------------------------------------------------
以下のようなプログラムを書いたのですが、自分が予測していた動作と異なり、困っています。
私は
-------------Start-------------
カウント----------->0
2で割り切れちゃった----------->0
カウント----------->1
2で割り切れなかった----------->1
カウント----------->2
2で割り切れちゃった----------->2
カウント----------->3
2で割り切れなかった----------->3
カウント----------->4
2で割り切れちゃった----------->4
-------------End-------------
という動作を期待していたのですが、実際は
-------------Start-------------
カウント----------->0
2で割り切れちゃった----------->0
カウント----------->1
2で割り切れなかった----------->1
カウント----------->2
2で割り切れちゃった----------->2
カウント----------->3
2で割り切れなかった----------->3
カウント----------->4
2で割り切れちゃった----------->4
2で割り切れなかった----------->5
2で割り切れなかった----------->6
2で割り切れなかった----------->7
-------------End-------------
となってしまいました。考えても、どうしてこのように動作するのか理解できなかったので、こちらに質問しました。よろしくお願いします(ソースコードは下です)。
-----------------以下、ソースコード-----------------
Main.java
public class Main
{
public static void main(String args[])
{
Saiki saiki = new Saiki();
System.out.println("-------------Start-------------");
saiki.playSaiki();
System.out.println("-------------End---------------");
}
}
Saiki.java
public class Saiki
{
private int counter;
Saiki()
{
counter = 0;
}
public void playSaiki()
{
if(counter < 5)
{
System.out.println("カウント----------->" + counter);
if(counter%2 == 0)
{
System.out.println("2で割り切れちゃった----------->" + counter);
counter++;
playSaiki();
}
System.out.println("2で割り切れなかった----------->" + counter);
counter++;
playSaiki();
}
}
}
No.2ベストアンサー
- 回答日時:
既に回答が付いていますが、2で割り切れる場合もifブロックの中での再起処理が終わった後にその下の処理が続けて行われるからですね。
下記の様にいくつか簡単な修正方法がありますが、修正後のソースから考えた方が分かりやすいかもしれません。
a. 2で割り切れる場合のifブロックの最後でメソッドを抜ける
例) ------------------------------------
if (counter %2 == 0)
{
System.out.println("2で割り切れちゃった----------->" + counter);
counter++;
playSaiki();
return; // この行を追加
}
----------------------------------------
b. ifで場合分けするのは、メッセージの表示部分だけにする
例) ------------------------------------
if (counter %2 == 0)
{
System.out.println("2で割り切れちゃった----------->" + counter);
}
else
{
System.out.println("2で割り切れなかった----------->" + counter);
}
counter++;
playSaiki();
----------------------------------------
回答ありがとうございます。
疑問に答えるだけでなく、改善策まで書いてくれるなんて...ほんとに感謝です。
修正するなら、2つ目のコードの方が無駄が少なくなくなりそうなので、それでやってみます。
No.3
- 回答日時:
ちょっと考えればわかるけど、
以下は playSaiki()の先頭に来たときのスタックトレースもどきです。
最初ぐんぐん潜っていって、戻り際にも3個出力するので、
0~7が出力されるのは明らかでしょう。
playSaikiは pSと略記してます。
pS() counter==0
pS() 割切->pS() counter==1
pS() 割切->pS() 割切ず->pS() counter==2
pS() 割切->pS() 割切ず->pS() 割切->pS() counter==3
pS() 割切->pS() 割切ず->pS() 割切->pS() 割切ず->pS()counter==4
pS() 割切->pS() 割切ず->pS() 割切->pS() 割切ず->pS() 割切->pS() counter==5
pS() 割切->pS() 割切ず->pS() 割切->pS() 割切ず->pS() 割切ず->pS() counter==6
pS() 割切->pS() 割切ず->pS() 割切ず->pS() couter==7
pS() 割切ず->pS() counter==8
スタックトレースもどき、ありがとうございます。
おかげで、視覚的にも問題を理解することができました。
今度またこのように再帰的にプログラミングする際は、自分でしっかり流れを追えるように、スタックトレースみたいなものを書いてみます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語のポインターに関する警告
-
JSPやサーブレットでSystem.out...
-
JavaにはなぜGO TO ...
-
cookie使用サイトへのJAVAによ...
-
標準入力をするメソッドを作り...
-
「続行するには何かキーを押し...
-
IF関数でEmpty値を設定する方法。
-
ORA-01858: 数値を指定する箇所...
-
ループ処理の際、最後だけ","を...
-
System.err. printlnとSystem.o...
-
System.exit()の値を取得したい
-
動的配列が存在(要素が有る)か...
-
カタカナの小文字を大文字に変...
-
javaで質問です。 文字列2023/2...
-
1~100までの数字を表示したい
-
【C#】ハッシュテーブル(連想...
-
streamで送信されたArrayListを...
-
0dの意味を教えてください
-
VBAで配列の計算
-
[Ljava.lang.Stringってなんですか
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語のポインターに関する警告
-
JSPやサーブレットでSystem.out...
-
[JAVA]try 内の変数を外で!?
-
EclipseでJava
-
JAVAのDouble型の小数点以下の...
-
文字列の引き算
-
JAVA 文字色変更
-
「続行するには何かキーを押し...
-
nullcline
-
"add"とは?f
-
JavaにはなぜGO TO ...
-
java int integer
-
JAVAのエラーの意味が分かりま...
-
LC発振回路-ループ利得
-
vb6 オブジェクトライブラリは...
-
String#matchesメソッドが環境(...
-
java教えてください。
-
javaで判別式のプログラミング...
-
エクセルマクロ文で、赤文字セ...
-
DOMで要素の値がNULL
おすすめ情報