Javaの学習を始めて数週間の初心者です。
皆さんのお知恵を貸してください。
条件分岐、ループ、配列、メソッドを使用したプログラムを作成する、
という課題です。習っただけでなく自分でちゃんと使えるか、という意図だと思います。
素数を判定するプログラムにしようと考えました(もっと単純なもので構わないのですが、思いつかなかった…)。
ネットを検索して考え方を参考にしながら、書いてみました(コピペではないです)。
不細工で読みにくいかもしれませんがよろしくお願いします。
概要(問題のソースは最下部)
・キーボードで3つの数字を入力し、それらを配列numに代入する(readLine使用)。[メソッド][配列]
・(ここからペーストしたソース)配列をfor文で足し込み合計値をsumに代入。[ループ]
・2以上とそれ以外に分ける(素数は2~)。[条件分岐]
・2以上、sum未満の数で順番に割っていく。
・1回でも割り切れたらboolean型sosuにfalseを代入、処理を終了させる。
(ここには載っていませんが、sosuはtrueで初期化済み)
・sosuがtrueかfalseかで表示を変える。
とりあえずソースを書いてコンパイルも通り、実行した結果も一応私の意図通りに動きます。。
が、これを講師の方に動きを説明しないといけません。一つ一つの動きは理解できるのですが、
ifの入れ子のブロックで処理がどう移っていくのかが不明瞭です。
お訊きしたいのは以下のケースで処理がどう動くのか、です。理由もお願いします。
(1)2つ目のfor文、1回目でfalseの場合(例えばsumが2の時)
…2の場合、「素数です」と表示されますが、改めて読むと「elseに飛んでsosu = falseになるのでは?」
という疑問があります。具体的な内容を伏せて講師の方に訊いてみると「上のif文でtrueになっても
その下のfor文でfalseならばelseに飛ぶはず」と言われました。
(2)2つ目のif文、falseになった場合
…この場合、falseなら素数と判定された、と思っていて実行結果もそのようになるのですが、
「elseに飛ぶ、が正しいならおかしくないかな?」と感じます。
(3)breakの後
…大体上と同じ疑問です。
(4)要は入れ子になっている場合、どこに処理が移るかがちゃんと解っていないのだと思います。
このような場合の読み方のアドバイスをお願いします。
情報に不足があればご指摘ください。
↓ここからソース↓
(略)
System.out.println("※合計値はint型の範囲内になるよう注意してください。");
(略)
int sum = 0;
for (int i = 0; i < num.length; i++) {
sum += num[i];
}
if (sum >= 2) {
for (int i = 2; i < sum; i++) {
if (sum % i == 0) {
sosu = false;
break;
}
}
} else {
sosu = false;
}
if (sosu == true) {
System.out.println("\n合計値" + sum + "は素数です。");
} else {
System.out.println("\n合計値" + sum + "は素数ではありません。");
}
(以下略)
No.3ベストアンサー
- 回答日時:
> 「上のif文でtrueになってもその下のfor文でfalseならば
> elseに飛ぶはず」これは正しいでしょうか?
いいえ,間違っています。
--------
01 if (sum >= 2) {
02 ■ for (int i = 2; i < sum; i++) {
03 ■● if (sum % i == 0) {
04 ■●★ sosu = false;
05 ■●★ break;
06 ■● }
07 ■ }
08 } else {
09 □ sosu = false;
10 }
--------
上記のコードにおいて,
01行目の if (sum >= 2) { が真のときに実行される■のブロックと,
それが偽のときに実行される 08行目 else { 以降の□のブロックは,
二者択一の関係にあります。
02行目,03行目,05行目が実行されたとしても
それらはすべて■ブロック内にある命令ですから,
□ブロックに実行が移ることはありません。
ちなみに,
05行目の break は,もっとも内側にあるループ(今回は,02行~07行のforブロック)に作用する命令であり,このループから脱出するという機能を実現しています。
したがって,
「05行目 break; の実行」→「forループを脱出して 07行目の次に移動」→「08行目の }で ■ブロックの実行もすべて終了」→「(if{} else{}の固まりの外にある)10行目の次の命令に移動」という実行の流れになります。
----------------
> if (sum >= 2) { // sumが2ならここはtrueですよね。
> for (int i = 2; i < sum; i++) {
> // iを2で初期化するので2 < 2となりfalseである
> と理解するのは間違いでしょうか?
そこまでの理解は正しいです。
回答No.1は次のことを指摘しているわけです。
「この場合のループ継続条件 2 < 2 はfalseなので,●で示されたforブロックの内部は一度も実行されない。前述の理由で □ブロックに実行が移ることもない。つまり,sum=2 の場合は 04行目も09行目も実行されないから,質問文に提示されていない「(略)」の箇所のコードで設定されたsosuの値がそのまま適用される」
お礼をしたつもりができていませんでした…大変失礼致しました!
遅くなりましたが、
■●★を使った視覚的な説明は大変解りやすく納得出来ました。
これからも頑張って学習を進めて行きたいと思います。
ありがとうございました。
No.2
- 回答日時:
変数の値を追いかけて、このプログラムのルートを全て通るにはどのような変数の値をとれば良いかを考えます。
影響を与えるのはsumだと考えます(readLineによる入力はどうとでもできるので)。
このプログラムでは、
sumが0以下の場合
sumが1の場合
sumが2の場合
sumが3以上の場合
で動作が異なると考えられます。
>iを2で初期化するので2 < 2となりfalseであると理解するのは間違いでしょうか?
falseとなり、forブロックは実行されません。
forブロックは実行されないので、変数sosuがfalseになる機会がなく、変数sosuの初期値がtrueなので、sum==2の場合は「合計値 2 は素数です。」という結果が得られています。
>…2の場合、「素数です」と表示されますが、改めて読むと「elseに飛んでsosu = falseになるのでは?」
飛ぶと思われるelseブロックにSystem.out.printlnを挿入して、実際にsum==2として実行してみると良いと思います。
>その下のfor文でfalseならばelseに飛ぶはず
この文だけを読む限りは飛びません。if~elseとforの判定処理は独立しているからです。
No.1
- 回答日時:
入れ子になってるならどう対応するのかを考えなきゃならない. マーカーなりボールペンなりで対応関係に色を付けてみたら?
あと, (1) で sum が 2 だと「2つ目のfor文、1回目でfalseの場合」には当てはまらないよ.
この回答への補足
ご回答ありがとうございます。
> (1) で sum が 2 だと「2つ目のfor文、1回目でfalseの場合」には当てはまらないよ.
あれ、そうなのですか…?
if (sum >= 2) { // sumが2ならここはtrueですよね。
for (int i = 2; i < sum; i++) { // iを2で初期化するので2 < 2となりfalseであると理解するのは間違いでしょうか?
もしかして私基本的な勘違いしてたりするのかな。
ソースとテキストfor文の箇所を見返していますがわからない…。
自分のプログラムなのに混乱してきました(笑)。もう少し考えます。
後、「上のif文でtrueになってもその下のfor文でfalseならばelseに飛ぶはず」
これは正しいでしょうか?
※投稿した後でソースのTabインデントが無効になっているのに気付き、
(私が)読みにくいので、スペースで下げます(内容は同一)。
(略)
System.out.println("※合計値はint型の範囲内になるよう注意してください。");
(略)
int sum = 0;
for (int i = 0; i < num.length; i++) {
sum += num[i];
}
if (sum >= 2) {
for (int i = 2; i < sum; i++) {
if (sum % i == 0) {
sosu = false;
break;
}
}
} else {
sosu = false;
}
if (sosu == true) {
System.out.println("\n合計値" + sum + "は素数です。");
} else {
System.out.println("\n合計値" + sum + "は素数ではありません。");
}
(以下略)
ご回答ありがとうございました。
皆さんのアドバイスを総合するとより理解が深まりました。
これからは対応関係を常に意識するように心がけたいと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java java 引数 戻り値のあるメソッド 3 2023/02/12 06:23
- Visual Basic(VBA) ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています 17 2022/12/07 12:03
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- Visual Basic(VBA) マクロVBA 1シートをまとめる 閉じ方 初心者 SOS! 1 2022/06/17 14:54
- PHP PHPの構文で間違えが分からない 5 2022/07/11 16:38
- C言語・C++・C# このプログラミングの問題を教えてほしいです。 キーボードからデータ数nとn個のデータを入力し、平均値 3 2022/12/19 22:51
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- PHP アップロード画像数でCSSを分けることに成功したのですが、画像の横に文字を並べることが出来ません。 3 2023/07/28 17:16
- C言語・C++・C# C言語階乗の総和を求める 2 2023/03/04 23:31
- Java java 次の機能を有するメソッドを自クラスに作成し、実装したいです。 機能 名前判定機能 →名前が 3 2022/06/16 16:08
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
split関数で区切り文字がない場合
-
Javascriptの値をJava(JSP)へ渡...
-
Javaで年月の取得(YYYYMM形式で)
-
「ワークスペースをビルド中」...
-
jasper.exceptionとは?
-
javaからVBAを実行する方法を教...
-
Eclipse(JAVA)のデバッグで他...
-
eclipseでスタックサイズを変更...
-
eclipse実行ができない
-
Worksheet_Changeが動かない
-
eclipseのjavaを実行できない
-
JAVAにのeclipseに関する質問で...
-
Java で開発できるマイコンはあ...
-
環境変数設定で
-
JavascriptからJavaを実行する
-
バイナリーコードと、ソースコ...
-
実行可能jarを実行できない
-
eclipseが使えません
-
Microsoft Office 2003 Power ...
-
JAVAでアプレットのエラー(ecl...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Eclipse(JAVA)のデバッグで他...
-
split関数で区切り文字がない場合
-
JAVAにのeclipseに関する質問で...
-
Javascriptの値をJava(JSP)へ渡...
-
jasper.exceptionとは?
-
「ワークスペースをビルド中」...
-
eclipseでスタックサイズを変更...
-
eclipseのjavaを実行できない
-
Javaで年月の取得(YYYYMM形式で)
-
コミット前の更新データをチェ...
-
eclipse実行ができない
-
Eclipseで実行>Javaアプリケー...
-
エクリプスで実行時、最新クラ...
-
Eclipse 実行→Javaアプリケー...
-
eclipseで「サーバーで実行」表...
-
Google Colabでimport soxが出...
-
環境変数設定で
-
Javascriptのパーミッション
-
Spyder上のPythonでinputが実行...
-
NoClassDefFoundError: javax/m...
おすすめ情報