• ベストアンサー

独習C 素数テスタ・・・分からない

忙しい中失礼します。 ”素数”を確認するプログラムについて質問があります。 現在独習Cを用いて勉強中なのですが、下記のプログラム理解に苦しんでいます。 宜しければアドバイスを下さい。 下記のプログラム/*素数テスタ*/内から、 質問(1)部:for(; num <=1; )の意味は’1’よりも大きな数字を入れれば、for文のループを抜ける→この考えで合っている、と自分では思っていますが、間違っているのでしょうか? ご指摘願います。 質問(2)部: 1.num=5の場合、for ( i=2; i <= num / 2; i = i+1) → i <= num / 2はi <= 2となる。→i <= 2となり、for文のループを抜ける。→ if ((num % i) == 0) の条件は成り立たない。→ is_prime = 1のため、"素数です"と表示される。→納得! 2.num=9の場合、for ( i=2; i <= num / 2; i = i+1)→  i <= num / 2は i(=2) <= 4となり、 i = i+1の’i’部が’4’となった後for文のループを抜ける。→if ((num % i) == 0)はnum % iは 9%4で’1’余り、となり、if ((num % i) == 0) の条件は成り立たない。→is_prime == 1 の状態がキープされる。→"素数です"と表示される、と思いきや"素数ではありません"と表示される。 で、ここで何故"素数ではありません"と表示されるのかが分かりません。頭の中では’9’が素数ではないのは分かりますが、プログラムの中でどういう経路を辿り、"素数ではありません"と表示されるのでしょうか。その過程の説明を欲しています。 宜しければ、アドバイスを下さい。 /*素数テスタ*/ #include <stdio.h> int main(void) { int num = 0, i, is_prime; for(; num <=1; ){ //質問(1) printf("判定したい数を入力して下さい: "); scanf("%d", &num); } /*約数があるかどうかを調べる*/ is_prime = 1; for ( i=2; i <= num / 2; i = i+1) //質問(2) if ((num % i) == 0) //質問(2) is_prime = 0; //質問(2) if (is_prime == 1 ) printf("素数です"); else printf("素数ではありません"); return 0; }

質問者が選んだベストアンサー

  • ベストアンサー
  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.6

> 「何かの処理」は”0”回通る 予想通りのお答え、ありがとうございます。 思ったとおり、for文の本質がおわかりになっていないようです。 くだんのfor文は、以下の動きをします。 1)iを10で初期化する。 2)i <= 10 の条件を満たしているので、「何かの処理」を実行する。 3)iに1を加える。iは11になる。 4)i <= 10 の条件を満たさなくなったので、ループから抜ける。 というわけで、正解は「1回実行する」です。 ちなみに、くだんのfor文は、「何かの処理」にcontinue; を含んでいない場合、 以下の文と等価です。 i = 10; while (i <= 10) {  /* 何かの処理 */  i++; } while文の意味合いが「カッコ内の条件を満たしている間、 { ~ }の中を実行し続ける」というものであることとあわせて、 for文の意味合いを今一度ご確認ください。

jpncndgoo2
質問者

お礼

 asuncionさん回答ありがとうございました。  ”予想通りのお答え、ありがとうございます。”→!やった正解だ!と私の心の中では少し喜びましたが、それから先の文を読んで、さっき喜んだ自分が恥ずかしくなりました。  とはいえ、asuncionさん貴重な時間の中の丁寧な指導及び回答ありがとうございました。  上記の回答は!そうだったのか!と思える程、私の中では衝撃的な”真実”でした。  いい勉強ありがとうございました。

その他の回答 (5)

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.5

for (i = 10; i <= 10; i++) {  /* 何かの処理 */ } というfor文を書いたとき、「何かの処理」のところを 何回通りますか?

jpncndgoo2
質問者

補足

私なりに回答しますと、 「何かの処理」は”0”回通る です。 理由は 1)i=10がiのアドレスに入っている 2)i<=10で条件を満たしている 3)i++の処理を行わない からです。

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.4

> 2)i++(i=i+1の省略型)を使い1ずつ足し算を行う。 > 3)i==10となった時、i <= 10の条件を満たすので、forループ条件から抜ける。 iが10のとき、くだんのfor文によるループの中身を 実行すると思いますか?実行しないと思いますか? for文によるループを継続する条件と ループから抜ける条件とを取り違えているように見えます。

jpncndgoo2
質問者

お礼

!ANo.5が先に答えられる、と思い先に書き込みました。が、 「iが10のとき」による回答は、ANo.5により、”実行しない”と思います。 ループを継続する条件:for ( i=1; i <= 10; i = i+1)であれば、i=10になるまで、ループを継続する、で下の条件に行く ループを抜ける条件:i=10となる → i<=10の条件を満たす → ループに入る必要なし とプログラム側で判断する → ループから抜ける 以上が私の回答です。

  • uta3
  • ベストアンサー率70% (21/30)
回答No.3

質問(1)の内容からおそらくfor文は理解されているのでしょう。 質問(2)は括弧が無いために勘違いされたのでしょうか。 以下のコードと同じ意味ですよ。 for( i=2; i <= num / 2; i = i+1) {   if((num % i) == 0) {     is_prime = 0;   } }

jpncndgoo2
質問者

お礼

!一発で分かりました。 簡潔明瞭な回答ありがとうございました。

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.2

> 1.num=5の場合、for ( i=2; i <= num / 2; i = i+1) > → i <= num / 2はi <= 2となる。→i <= 2となり、for文のループを抜ける。 > → if ((num % i) == 0) の条件は成り立たない。 > → is_prime = 1のため、"素数です"と表示される。→納得! 納得してはいけません。結論は正しいですが、過程が誤っています。 1)iを2で初期化する。 2)i <= num / 2 の条件が成立する。for文のループを実行する。抜けるのではありません。 3)if ((num % i) == 0) の条件は成立しない。 4)iに1を加える。3になる。 5)i <= num / 2 の条件は成立しない。ここで、for文のループから抜けます。 6)is_primeは1のままなので、"素数です"と出力する。 よろしいでしょうか? 例えば、 for (i = 1; i <= 10; i++) というfor文の動きを日本語で説明すると、どうなりますか?

jpncndgoo2
質問者

補足

asuncionさん丁寧なアドバイスありがとうございます。 その回答で十分満足しています。 for (i = 1; i <= 10; i++)について、私なりにお答えします。 1)iを1で初期化する 2)i++(i=i+1の省略型)を使い1ずつ足し算を行う。 3)i==10となった時、i <= 10の条件を満たすので、forループ条件から抜ける。 以上です。 これが私の回答です。

  • Werner
  • ベストアンサー率53% (395/735)
回答No.1

> 質問(1)部:for(; num <=1; )の意味は’1’よりも大きな数字を入れれば、for文のループを抜ける 「numが1以下」と言う条件が満たされている間ループが継続されることになるので、 言い換えるとnumが1を超えるとループを抜けることになります。 なので、あってます。 あと、別にforでも良いんだけど、普通は継続条件だけならwhileを使うと思う。 > 質問(2)部 num==9ならi==3の時にif文の条件は満たされます。

jpncndgoo2
質問者

お礼

アドバイスありがとうございました。 質問(2)部は、ANo.1の回答を読んだ後、Wernerさんのいわんとすることを納得しました。 ありがとうございました。

関連するQ&A

専門家に質問してみよう