• ベストアンサー

誤作動の原因を教えてください

大学の課題で、あるプログラムを作成することになったのですが、実行しても意図したこととは違ってしか実行しなかったので、その原因と、どう修正すべきかを具体的に教えてください。 技術者向けというわけでもなさそうですが、C言語初心者の私には、小一時間考えてみても分からなかったので、お手柔らかに教えていただけると幸いです。 課題の内容は以下の通りです。 コンソールから入力した整数N以下のすべての素数を表示するプログラムを作成せよ。その際に次の点に配慮せよ。 ・2は素数である。 ・3は素数である。 ・4以上の偶数は素数ではない。 ・小さい方から割って、割り切れるかどうかを確認する場合に、素数かどうかを確認したい数の平方根より大きい数で割って確認する必要はない。 さらに、1行に10個の素数を印刷したら、改行するように改良できていたら加点する。 次に実際に私が作成したプログラムを載せます。 ソースをコピペしただけなので、コメント欄がそのまま表示されていたり字下げや改行が見にくくなっていたりしているとは思いますが、ご了承ください。 #include <stdio.h> #include <math.h> #define WIDTH 10 int main (int argc, const char * argv[]) { int i, j, k, n, flag; printf("自然数を入力してください\n"); scanf("%5d",&n); k = 1; printf(" 2"); //2は明らかに素数なので始めから表示するようにしておく。 for(i=3; i<=n; i+=2){ //3から調べていくが、偶数は明らかに素数ではないので奇数だけ調べていく。 flag = 0; for(j=1; j <= sqrt(i); j+=2){ //平方根以上の数で割って確認する必要はない。3以上の素数は奇数であるから偶数では割り切れない。 if(j != 1 && i%j == 0){ //もしもiが1以外で割り切れたら、 flag = 1; //素数ではないので終了する。 break; } if(flag == 0){ printf(" %5d",i); k++; if(k >= WIDTH){ printf("\n"); k=0; break; } } } } printf("\n"); return 0; } そして実行結果ですが、ここで問題が出てしまいました。 実際の実行結果は諸事情によりここでは載せられませんが、例えば20という数値を入力したときには、 自然数を入力してください 20 2 3 5 7 9 11 11 13 13 15 15 15 17 17 19 19 というようにディスプレイ上に出力されたわけです。 ご覧の通り、 (1)奇数が全て表示されてしまっている(素数ではない9や15が表示されている)。 (2)11以降の数が複数回表示されてしまっている。 (3)その上で1行に10個数が出力すると改行するようになっている。 という点が分かります。 ちなみに大学のPCの動作環境についてはよく分からないし、あまり公言はできませんが、OSはMacで、ソフトはXcodeのCommand Line Utility中のStandard Toolを利用しているということだけは言っておきます。 課題の締め切りは6月29日12時までとなっているので、それに間に合うように解答していただければ幸いです。よろしくお願いします。

みんなが選んだベストアンサー

  • ベストアンサー
  • f272
  • ベストアンサー率46% (8111/17329)
回答No.4

致命的なのは for(j=1; j <= sqrt(i); j+=2){ ...(1) のループの中で if(j != 1 && i%j == 0){ ...(2) という判定を行っているが、(1)の最初の値であるj=1のときには必ず(2)がfalseになるのでif(flag == 0){ の中に入って素数だということにされていることです。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (6)

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.7

>今週は毎日のように課題と試験があるので、ゆっくり6日間考える時間はとれないというわけです そういう理由があれば、人からもらった回答をそのまま自分のものとして 提出するのはありだと考えているのですか? そういうことを繰り返していると、やがて「思考停止状態」に陥ったりしませんか?

全文を見る
すると、全ての回答が全文表示されます。
  • yama5140
  • ベストアンサー率54% (136/250)
回答No.6

(適切な回答が多く、解決しそうなので、年寄りのソース投稿は締め切り前日に、と思ったのですが忘れちゃいそうで・・) >誤作動の原因を教えてください  これについては、No.2 さん以降の「回答」をじっくり考えて下さい。  このとき、手元のソースの「字下げ」幅を2倍程度にすると、より早く解決するかもしれません。  「原因」が判明し、正しく動くようになってから、下のソースを参照してみて下さい。 ・質問者様のソースをちょっぴり改変しています。    flag = 1; を「素数」としています(フラグの使い方として、こちらの方が自然?)。    素数の数を、iCnt でカウントアップしています。    数学関数は使っていません(平方根ではなく平方を用いています)。    入力自然数までの「素数」の数を出力します(ちなみに、132 番目は、743 らしいです http://ja.wikipedia.org/wiki/743 )。    (投稿上の都合により、_ 使用、コピペ後半角空白に)    ! について、「初めて見た、ビックリした」のなら、「 0 == 」に読み換えて下さい。 注:あくまで「参照/試行」にとどめて下さい。自分のが正しく動いたら、思いっきし感動して下さい( ← ★今後に重要)。 #include <stdio.h> #define  WIDTH  10 int  main( int argc, const char *argv[] ) {   int  i, j, iNum, flag;   int  iCnt = 2;  // 2, 3 表示の2個   printf( "3以上の自然数を入力してください\n" );   scanf( "%5d", &iNum );  // 5桁まで   printf( "_____2_____3" );  // 2, 3 は明らかに素数なので始めから表示。   for( i = 5; i <= iNum; i += 2 ){  // 5 から調べていくが、偶数は明らかに素数ではないので奇数だけ調べていく。     flag = 1;  // 「素数」で初期化     for( j = 3; ( j * j ) <= i; j += 2 ){  // 平方「超」の数での確認不要。3 以上の素数は奇数であるから偶数では割り切れない。       if( ! ( i % j ) ){  // 割り切れるか         flag = 0;         break;       }     }     if( ! flag )  continue;  // 素数ではないので次へ     if( ! ( iCnt++ % WIDTH ) )  printf( "\n" );     printf( " %5d", i );   }   printf( " (%4d)\n", iCnt );   return( 0 ); } 注:「字下げ」に全角空白2ケを用いています。コピペ後、タブに一括変換して下さい。

全文を見る
すると、全ての回答が全文表示されます。
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.5

設問に 1) 2は素数 2) 3は素数 3) 4以上の偶数は素数でない 4) 小さい方から割って、割り切れるかどうかを確認する場合に、素数かどうかを確認したい数の平方根より大きい数で割って確認する必要はない とあるのに なぜ3を調べるのでしょう また『素数は自身と1以外の約数を持たない数』のはずですから 4) の検査をする際に 1からやる必要があるのでしょうか 1から検査をするため 判断用のif文に j!=1 といった無駄な条件を付け加える必要が出てきます 後は f272氏の回答のように 素数の最終判定の位置がおかしいため 検査した値がすべて素数といった結果になってしまっているのでしょう

全文を見る
すると、全ての回答が全文表示されます。
  • ESE_SE
  • ベストアンサー率34% (157/458)
回答No.3

言語を問わず、プログラムの基礎構造は ・代入・演算 ・条件分岐 ・ループ でほぼ語り尽くされます。 どこかの条件に間違いはありませんか? ループに入る条件、ループから抜ける条件に不備はありませんか? 11から動作がおかしいのであれば、11が表示されるケースについてプログラムがどのような挙動を取っているか、プログラムの動きを追い掛けましょう。

全文を見る
すると、全ての回答が全文表示されます。
  • Quant
  • ベストアンサー率18% (23/122)
回答No.2

'}'の位置を調べてみましょう。 またbreak;もいらないところがあります。これのおかげで40、50と入れても10個以上は表示されない。

全文を見る
すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

>課題の締め切りは6月29日12時まで まだ6日近くもあるではないですか。 それまでに、「ご自分で」じっくり考えてみましょう。

kitoplus
質問者

補足

それは承知しているつもりですが、今週は毎日のように課題と試験があるので、ゆっくり6日間考える時間はとれないというわけです。 ここで締め切りの日をあえて示しているのは、一般的にみて時間が無いからではないのです。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 間違いを指摘して頂けませんか?(切実)

    私は大学で春からプログラミングの基礎を学び始めたプログラミング初心者です。 今、if関数のネストについて習っていて、if関数のネストを利用したプログラム作成の課題が出て、一応書いてはみたのですがどうしても上手くいきません。下に課題の内容と私の書いたプログラムを書いておきますので、間違っている箇所を指摘、修正して貰えませんか?宜しくお願い致します。 【課題】 次の項目に従ってプログラムを作成せよ。 (1)整数型の変数noを宣言 (2)「整数を入力してください。」と表示して改行 (3)キーボードから入力された値を変数noに代入 (4)入力された値が ・偶数で4で割り切れる数なら「整数○は偶数で4で割り切れます。」 ・偶数で4で割り切れない数なら「整数○は偶数だけど4で割り切れません。」 ・奇数で3で割り切れる数なら「整数○は奇数で3で割り切れます。」 ・奇数で3で割り切れない数なら「整数○は奇数だけど3で割り切れません。」 の○の位置にnoの値を当てはめて表示した後、改行 #include <stdio.h> main(void) { int no; printf("整数を入力してください。\n"); scanf("%d",&no); if(no/2==0,no%4==0){ printf("整数%dは偶数で4で割り切れます。\n",no); }else{ if(no/2==0,no%4!==0){ printf("整数%dは偶数だけど4で割り切れません。\n",no); }else{ if(no/2!=0,no%3==0){ printf("整数%dは奇数で3で割り切れます。\n",no); }else{ printf("整数%dは奇数だけど3で割り切れません。\n",no); } } } } ※なお、上のプログラムは全て左詰めになってしまっていますが、質問する上で表示出来なかっただけですので…実際にはちゃんと然るべき箇所にTabキーによる余白は入れてあります。

  • 祝日判定です。

    祝日判定 カレンダーですが、エラーが出てしまいます。どうかよろしくお願いいたします。ソースの一部です。 for (j=0; j<6; j++) { for (k=0; k<7; k++) { if (cal[i][j][k]==0) printf(" "); else if(hantei(yy,mm,dd,youbi) == 2){ printf("(%3d) ",cal[i][j][k]); flag = 1; // 日曜と祝日が重なったらflagをたてる } else if(hantei(yy,mm,dd,youbi) == 1 || flag == 1){ printf("(%3d) ",cal[i][j][k]); printf("\t"); flag = 0; } else if((i-1)%7 == 6){ // 土曜日 printf("%3d ",cal[i][j][k]); printf("\t"); } else{ printf("(%3d) ",cal[i][j][k]); //printf("%d"); //日付を出力 flag = 0; } if((i-1)%7 == 6) printf("\n"); //土曜のあとは改行 } int hantei(int yy,int mm,int dd,int youbi){ if((mm==3 && dd== (int)(20.8431 + 0.

  • 原因が分かりません!

    C言語の課題です 行列AとBの積Cの結果を表示して、Cの最大値最小値を表示せよというものです。 Cは正しい結果なのですが、最大値と最小値が正しくありません。 なぜこうなるのか原因が不明なので指摘お願いします 期限が7月1日なので早急に解答を寄せてもらえれば嬉しいです #include <stdio.h> int main(void) { int i, j, k; int a[2][2] = { {1,8}, {3,9} }; int b[2][2] = { {4,7}, {2,1} }; int c[2][2] = {0}; int max, min; puts( "matrix A =" ); for(j=0; j<2; j++){ for(k=0; k<2; k++){ printf( "%3d" , a[j][k]); } printf( "\n" ); } puts( "matrix B =" ); for(k=0; k<2; k++){ for(i=0; i<2; i++){ printf( "%3d" , b[k][i]); } printf( "\n" ); } puts( "AとBの積\nmatrix C ="); for(j=0; j<2; j++){ for(i=0; i<2; i++){ for(k=0; k<2; k++) c[j][i] += a[j][k]*b[k][i]; printf( " %3d" , c[j][i]); } printf( "\n" ); } { if( j==0 && i==0 ){ max = c[j][i]; min = c[j][i]; } if( max < c[j][i] ) max = c[j][i]; if( min > c[j][i] ) min = c[j][i]; max = c[0][0]; min = c[0][0]; printf( "行列Cの最大値 : %d\n", max, c[j][i] ); printf( "行列Cの最小値 : %d\n", min, c[j][i] ); } return (0); }

  • C言語で困っています...

    入力した数値の列だけ○と×を縦に、段々になるように表示する (最後の行は×にならなければいけない)プログラムを作成しています。 (実行例) ○と×を表示します。何列?:10            ×           ○×          ×○×         ○×○×         ×○×○×       ○×○×○×      ×○×○×○×    ○×○×○×○× ×○×○×○×○× ○×○×○×○×○× 途中までプログラミングできたのですが、 偶数の数値を入れたときはきちんと最後の行は×になっても 奇数の数値を入力すると○が最後の行になってしまい、うまくいきません。 どこがだめなのでしょうか? どなたか教えてください。 /* 入力した数値の列だけ、○と×を縦に、   段々になるように表示する(最後の行は×になる) */ #include <stdio.h> int main(void) { int i, j, n; printf("○と×を表示します。何列?:"); scanf("%d", &n); for (i=0; i<n; i++){ for (j=0; j<n; j++){ if (j >= (n - 1) - i){ if (j % 2 == 0) printf("○"); else printf("×"); } else printf(" ");//全角スペース } printf("\n"); } return 0; }

  • C言語!プログラム書いたのですがエラーです!

    課題内容 キーボードから数字を入力してその値までの合計を表示する。 さらに入力した値が偶数なら0から入力した値までのすべての偶数の和を 入力した値が奇数なら1から入力した値までのすべての奇数の和を表示するプログラム。 #include<stdio.h> int main(void) { int i, n, sum; sum=0; scanf("%d",&n); printf("入力値:%d\n", n); if(n%2 = 0) { for(i=0;i<=n;i+=2) { sum=sum+i; } printf("合計値:%d\n",sum); } else { for(i=1;i<=n;i+=2) { sum=sum+i; } printf("合計値:%d\n",sum); } return(0); } これでコンパイルすると10行目に左辺値が必要とでます。 どうすればよいでしょうか? 教えてください。よろしくお願いします。

  • C *での三角形描画

    課題で*を使って三角形を描画するプログラムを作るんですが、ネットで見たかぎり、 #include<stdio.h> int main() { int n, i, j, k, l; printf("段数を入力してください:"); scanf("%d", &n); for(i = 0; i < n; i ++) { for(j = 0; j < n; j ++) { for(k = 0; k < n*n-i*n-j-1; k ++) printf(" "); for(k = 0; k < i; k ++) { for(l = 0; l < j*2+1; l ++) printf("*"); for(; l < n*2; l ++) printf(" "); } for(k = 0; k < j*2+1; k ++) printf("*"); printf("\n"); } } return 0; } となっているのが、  段数を入力してください:2     *    ***   *   *  *** *** という風に表示されるので、これを  段数を入力してください:2     *    *** という形に表示させられるよう変更すべき箇所を教えてください。

  • 助けてください

    10は偶数で5の倍数です。 11は素数です。 12は偶数で6の倍数です。 13は素数です。 14は偶数で7の倍数です。 15は奇数で5の倍数です。 16は偶数で8の倍数です。 17は素数です。 18は偶数で9の倍数です。 19は素数です。 20は偶数で10の倍数です。 と出力させたいのですが、 H:\>java SuuNoSyurui 11は奇数で0の倍数です。 12は偶数で0の倍数です。 13は奇数で0の倍数です。 14は偶数で0の倍数です。 15は奇数で0の倍数です。 15は素数です。 16は偶数で0の倍数です。 17は奇数で0の倍数です。 17は素数です。 18は偶数で0の倍数です。 19は奇数で0の倍数です。 19は素数です。 20は偶数で0の倍数です。 -- Press any key to exit (Input "c" to continue) -- こうでてしまいます。 下のが立てたプログラムです。 public class SuuNoSyurui { public static void main(String[] args) { int i=1,j=2; int n1=10; int n2=20; int n=n2-n1; int baisu=0; for(i=1;i<=n;i++) { if (i%2==0){ System.out.println("\t"+(i+n)+"は偶数で"+baisu+"の倍数です。"); } else { System.out.println("\t"+(i+n)+"は奇数で"+baisu+"の倍数です。"); } for(j=3;j<=(i-2);j +=2) { if (((i-2)%j==0) && ((i-2)%2)==1){ System.out.println("\t"+(i+n)+"は素数です。"); } } } } }

  • C言語の問題

    以下はC言語の問題です。お教えください。 1000以下の素数を求めるプログラム prog.c を作成せよ。各素数を整数4桁で出力し、15個の素数を出力した時点で改行処理 を行うこと。作成したプログラムを提出せよ。 です。 僕の考えでは、 #include <stdio.h> #include <math.h> main(){ int i; int j; int ix; int k; printf("正の整数を入力して下さい: "); scanf("%d",&i); ix=(int)(sqrt((double)i)); k=0; for(j=2;j<=ix;j++) { if(i%j==0) { k=1; } } if(k==0) { printf("%d は素数です\n",i); } else { printf("%d は素数ではありません\n",i); } となると思うのですが。どうやら違うようです。全然わからないので、正しい答えを教えてください。

  • プログラムを組んだのにエラーが出る!!!

    #include <stdio.h> #include <stdlib.h> #include <math.h> int main(void) { int i, j; int m, flag, count; FILE *fp; if (NULL == (fp = fopen("prime.txt", "w"))) { printf("Cannot open output file\n"); exit(1); } count = 0; for (i = 2; i < 1000; i++) { m =sqrt(i); flag = 1; for (j = 2; j <= m; j++) { if (i % j == 0) { flag = 0; break; } count++; } if (flag) { printf("%4d ", i); fprintf(fp," %4d", i); } } printf("\n乗除回数:%d\n", count); fprintf(fp,"\n乗除回数 %d\n", count); fclose(fp); return 0; } (通常課題2-3 1000以下の正の整数値のうち,素数をすべて計算し,結果をファイルに格納するプログラムを作れ. .また、計算の実行の中で乗除を行った回数もあわせて表示し、ファイルに格納すること 実行結果 2 3 5 7 11 13 17 … 991 997 乗除回数:78022 どこが間違ってるのか指摘してください お願いします!

  • 一番大きい奇数を表示する

    scanf関数を使って数字を10回入力して一番大きなものを表示させるプログラムをつくったのですが、 さらに一番大きな奇数を表示するにはどうすればいいのでしょうか? 偶数=割り切れる 奇数=割り切れない というところまでは分かるのですが、以下のプログラムに奇数を判別するソースを追加するのにはどうすればいいのでしょうか。 #include <stdio.h> int main(void) { char str[1024]; char buf[10]; int i; int w; printf("文字列を10回入力して下さい:\n"); memset(str, 0, sizeof(str)); for (i = 0; i < 10; i++) { memset(buf, 0, sizeof(buf)); printf("input>\n"); scanf("%s", buf); } for (i = 0; i < 10; i++) { if ((buf[i] & 1) == 1) /* 奇数であるか */ { if (strcmp(buf, str) > 0) { strcpy(str, buf); } } } printf("output>\n%s\n" , str); getchar(); }

このQ&Aのポイント
  • 毎週5千円ずつタクシーを利用して車を持つよりも得か?1週間に1度車で外出するとして、毎週5000円ずつタクシーを使うと片道2500円のところまで行けます。年間で24万かかる車の維持費に対して、タクシーは半分の維持費で済むことになります。問題は東京の市街地の住宅街でタクシーの利用が限定的なことです。
  • タクシーを呼ぶスマホアプリは便利で、割引などもあることがあります。ただし、片道2500円ぐらいの料金でタクシーを呼ぶ場合、タクシーにとっては利益が少ない客と見なされる可能性があります。タクシー利用を検討する際には、アプリを利用して割引を活用すると良いでしょう。
  • タクシーを活用するメリットは、車を持つよりも経済的であることです。年間で24万かかる車の維持費に対して、タクシーは半分の維持費で済むため、コストを抑えて移動することができます。ただし、東京の市街地の住宅街ではタクシーの利用が限定的なため、利用可能な場所や時間帯を事前に確認することが重要です。
回答を見る