C言語の整数加算プログラムの問題と解説

このQ&Aのポイント
  • C言語の問題でわからないところがあります
  • 二つの整数値を読み込んで、小さい方の数以上で大きい方の数以下の整数を全て加えた値を表示するプログラムを作成するものなのですが、うまくいかなく困っています
  • 大きい方に37、小さいほうに28と入力するととても大きな数値になってしまいます。ループが間違っているのでしょうか?
回答を見る
  • ベストアンサー

C言語の問題でわからないところがあります

先ほども似たような内容で質問させて頂いたのですが、もう一度質問させてください。 最近C言語を勉強し始めたのですが、わからないところがあります。 二つの整数値を読み込んで、小さい方の数以上で大きい方の数以下の整数を全て加えた値を表示するプログラムを作成するものなのですが、うまくいかなく困っています。 他の書き方でやれば普通にいけると思うのですが、これだとできない理由がわからないと、もやもやしてしまうので・・・・ プログラムは以下の通りです #include <stdio.h> int main(void) { int n1,n2,n3,n4; puts("二つの整数を入力してください"); printf("整数1:"); scanf("%d",&n1); printf("整数2:"); scanf("%d",&n2); n3=(n1>n2) ? n2 : n1; n4=(n1>n2) ? n1 : n2; printf("%d以上%d以下の全整数の和は", n3,n4); int num=n3; /* numの最初の値は小さい方の値 */ int wa=0; /* n3が小さい方の数、n4は大きい方の数 */ do{ if (n1>n2) { wa=n4+num; /* 大きいほうの数(num)にsub(小さい方の数+0,2,3,4・・・)を足していく */ num=num+1;/* ここを通るたびにsubに+1 */ printf("%d",wa);} else { wa=n4+num; num=num+1; printf("%d",wa);} }while(num<n4); /* num<n4を満たさない=numが大きいほうの数よりも大きくなったらループを終了 */ printf ("です\n"); /* ですっす */ return 0; } これで大きい方に37、小さいほうに28と入力すると656667686970717273ととても大きな数値になってしまいます。 ループが間違っているのでしょうか? whileは whileの後の()の中身の条件を満たしているとにループする、と認識しているので、numが大きい方の数値より大きくなったとき、ループを終了するようにしているつもりです。 ここがどこか間違っているのでしょうか・・・? それから、初期化というのもいまいち理解していないのですが、intで宣言するときに、中に数値を格納しておく、という物だと思っています。 宣言の後にprintf("%d",num);などで確認すると、代入できているようなので、これは間違っていないと思うのですが・・・・、 間違っているところがざっとみて解りましたら、回答頂けるとありがたいです。 C言語を始めたばかりなので、できれば簡単に説明して頂けるとありがたいです。

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

  • ベストアンサー
noname#140082
noname#140082
回答No.7

No.1です。 ここに出てくる変数(n3,n4とか)を登場人物として、その役割を考えるとわかりやすくなるかと思います。 それぞれの役割は n1,n2=入力用、大小判定をした後は必要ありません。 n3=入力された最小値 n4=入力された最大値 wa=累積値 num=最小値から最大値までの可変値(28~37) ですからn3はnumに最初代入する以外使う必要はありません。 n4は、numがカウントアップするので、その最大値の判定で使用すればいいでしょう。 また、最終的に必要なのはwaなので、waはループの外で最後に表示すればいいでしょう。 (確認のためにあるのは構いませんが) あと、変数名はたとえば n3はn_min,n4はn_maxなどと意味がわかるようにすると考えやすくなると思います。

その他の回答 (8)

回答No.9

>他の書き方でやれば普通にいけると思うのですが、これだとできない理由がわからないと、もやもやしてしまうので・・・・ >これで大きい方に37、小さいほうに28と入力すると656667686970717273ととても大きな数値になってしまいます。ループが間違っているのでしょうか? 「656667686970717273」は wa=n4+num; printf("%d",wa); の指示通り、改行コード'\n'がないために「n4+num」の結果をそのまま表示したものです。 >whileは whileの後の()の中身の条件を満たしているとにループする、と認識しているので、numが大きい方の数値より大きくなったとき、ループを終了するようにしているつもりです。 >ここがどこか間違っているのでしょうか・・・? これは合っていますヨ。 ただ、条件式は「<=」でなければならない。 ・・・「=」がないと36までとなって、37が加算されていない計算結果となってしまうからです。 >それから、初期化というのもいまいち理解していないのですが、intで宣言するときに、中に数値を格納しておく、という物だと思っています。 >宣言の後にprintf("%d",num);などで確認すると、代入できているようなので、これは間違っていないと思うのですが・・・・、 Cは関数の中で単にint宣言した場合は、スタックメモリに設定されます。 http://www.g-ishihara.com/c_mm_01.htm ですから、その値は不定であるため、設定が必要なのです。 変数の宣言位置は好みの問題で、どこでも良いのですが、変数を最初に記述するのが一般的です。 ・・・理由は、見易いから。後から自分が見てもわかり易いように書く、保守管理が容易なように記述するプログラミングが奨励されています。 また、数値の設定もint宣言時であろうと後であろうと自由です。別に制限はありません。だって、コンパイルが通るでしょ。 気が付いたことは「if (n1>n2) else 」は上下が同じプログラムになっていることです。 これって、同じということは一つで済むということですから、一つにまとめるべきでしょう。 すると、↓のようになってスッキリします。 #include <stdio.h> int main(void) { int n1, n2, n3, n4; int num, wa; puts("二つの整数を入力してください"); printf("整数1:"); scanf("%d",&n1); printf("整数2:"); scanf("%d",&n2); n3=(n1>n2) ? n2 : n1; n4=(n1>n2) ? n1 : n2; printf("%d以上%d以下の全整数の和は", n3,n4); num=n3; /* numの最初の値は小さい方の値 */ wa=0; /* n3が小さい方の数、n4は大きい方の数 */ do{ wa = wa + num; /* 合計は変数num を加算したもの */ num = num + 1; /* 変数num を1増やす */ }while(num <= n4); /* num<=n4 の条件を満たすときループを継続 */ printf ("%d です\n", wa); /* ですっす */ return 0; }

  • luckymako
  • ベストアンサー率55% (29/52)
回答No.8

質問文へのコメントは他の方へお譲りして違う算法を参考までに書いてみました。 ガウスの方法です。 #include <stdio.h> main(){  int n1, n2, nt;  printf("整数1:"); scanf("%d",&n1);  printf("整数2:"); scanf("%d",&n2);  if(n1 > n2){   nt = n1;   n1 = n2;   n2 = nt;  }  printf("%d\n", (n2 - n1 + 1) * (n1 + n2) / 2); } 繰り返しを使用すると速度は O(n2 - n1 + 1)で、数値の個数に比例しますが、 ガウスの方法なら O(1)で、どれだけ二つの数値が離れていても常に同じ時間で計算が終わります。 実践で使うならこちらです、

  • KEIS050162
  • ベストアンサー率47% (890/1879)
回答No.6

難しく考え過ぎです。(いっぱい突っ込みどころが…) 単純に、ある数値nからもう一つの数値m(ただし、m>n)の和を求めるだけですから、既に指摘の通り、while文のif文は不要です。 私も#2さんの例をお勧めします。(等差数列の公式を使ってもいいですけどね) これで解決なのですが、大事なことは、何故”656667686970717273”などと表示されたか、をちゃんと原因を見つけて治すことです。 これは、while文の中にある、デバッグの為のprintf("%d",wa) が出力されているのですね。 大きい数値 37、小さい数値 28を入力したので、 wa=n4+num;  の結果は、65になります。 以降、numの値が36になるまで、1づつ足されていくので、65 ~ 73 までが連続で表示されただけですね。 ご参考に。

回答No.5

初期化というのは、基本的には変数を空にしておくことを言います。 int hoge; という宣言だけでは、hogeの中身が何であるのかわかりませんので、 hoge = hoge + 1; の結果が何になるかが分かりません。 その為に、最初に「hogeの中身は最初は0ですよ」と明示的に決める為に、 hoge = 0; とするのが初期化です。 > 656667686970717273 これは大きな数字が出力されているのではなく、 65 66 67 : 73 と、65~73までの数字が連続した表示です。 そのように出力される理由は printf("%d",wa); がループ内に存在する為に、足し算をする度に出力されてしまっているからです。 恐らく結果の出力はループが終わった後に1回で良いと思われますので、 do{}while() の外側、それよりも後に出力しましょう。 そうすると「ソースに書いた通り」の正しい結果が表示されます。 その結果が「考えた通り」の数字であれば良いのですが、 異なる場合は再度、ソースを見直す必要があります。

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.4

>これで大きい方に37、小さいほうに28と入力すると656667686970717273ととても大きな数値になってしまいます。 「65」を表示した後『改行せずに』「66」を表示、 さらに『改行せずに』「67」を表示、 さらに『改行せずに』「68」を表示…… となっているだけです。 printf()の書式指定で改行入れるとか半角スペースを入れるとか、区切りが判るように出力すればよろしいでしょう。 # 改行だとスクロールアウトしてしまうかも知れませんのでご注意を。

  • tossy2011
  • ベストアンサー率17% (3/17)
回答No.3

waに毎回大きい数字を足しているからではないでしょうか また、numの初期値に代入されるべき値は小さい方の数+1のはずなので( n3 + 1 ) になると思います

回答No.2

まず、一体なんのために、大小を比較して、大きい方、小さい方を別変数に代入したかを考える。 同じ手順で、操作するためでしょ?その後に、なんでまた元の変数(n1,n2)の比較をして、処理を二通り書くの? n3とn4を使えば、 for(wa=0; n3<=n4; n3++){ wa += n3; } printf(”和=%d\n",wa); で、解決でしょ?

noname#140082
noname#140082
回答No.1

>大きい方に37、小さいほうに28と入力すると まず、質問者さんがやりたいのは、この質問文で言えば wa=28+29+30+…+36+37 ですよね。 それをnumを1つずつカウントアップしながら、実現しようとしているわけですから、デバッグ環境があれば1ステップずつ止めながらか、無ければprintf()で、wa,numの値を確認すればいいでしょう。 また、whileの中のループで if (n1>n2) と判定している箇所がありますが、その判定をしても結局どちらも同じ処理をしているのですから、この判定自体が不要となります。 また、 printf("%d",wa); は printf("%d\n",wa); などとして区切りをわかるようにした方がいいです。(カンマでもいいですが)

関連するQ&A

  • C言語初心者です。次の問題で質問です。

    (問題) 二つの整数値を読み込んで、小さい方の数以上で大きい方の数以下の整数を全て加えた値表示するプログラムを作成せよ。 (自分の解答) #include <stdio.h> int main(void) { int num1,num2; int sum=0; do { printf("整数1>整数2となる整数をそれぞれ入力してください\n"); printf("整数1:"); scanf("%d",&num1); printf("整数2:"); scanf("%d",&num2); if (num1 < num2) printf("整数1>整数2としてください\n"); } while (num1 < num2); printf("%d以上%d以下の全整数の和は",num2,num1); for (num2;num2 <= num1;num2++) { sum=sum+num2; } printf("%dです。",sum); return 0; } これでも一応正しく実行されるのですが、ごちゃごちゃしてるので簡潔に書けないでしょうか? 回答お願いします。

  • プログラムの勉強でわからないところがあります

    明解C言語の入門編、演習4-3 二つの整数値を読み込んで、小さい方の数以上で大きい方の数以下の整数を全て加えた値を表示するプログラムを作成するものなのですが、うまくいかなく困っています。 他の書き方でやれば普通にいけると思うのですが、どうしてこれだとできないのかがわからないとすっきりしなくって・・・ 以下のようなプログラムで試しています。 #include <stdio.h> int main(void) { int n1,n2,n3,n4; puts("二つの整数を入力してください"); printf("整数1:"); scanf("%d",&n1); printf("整数2:"); scanf("%d",&n2); n3=(n1>n2) ? n2 : n1; n4=(n1>n2) ? n1 : n2; printf("%d以上%d以下の全整数の和は", n3,n4); int num=n1; int sub=n2; int wa; printf("num=%d sub=%dで",num,sub); do{ if (n1>n2) { wa=num+sub; /* 大きいほうの数(num)にsub(小さい方の数+0,2,3,4・・・)を足していく */ sub=sub+1;/* ここを通るたびにsubに+1 */ printf("%d",wa);} else { wa=sub+num; num=num+1; printf("%d",wa);} }while(sub!=n1 || num !=n2); /* 小さい方の数に1足していったものが大きい方の数と等しくなったら0を生成し終了 */ printf ("です\n"); return 0; } このプログラムで試すと、延々と計算をし続けていってしまうのです。 whileあたりがおかしいのかと思ったのですが、どこがおかしいのかわからなくって・・ whileは、中の数字が0を生成する場合止まる、というものだったと思うので、小さい方の数字に1ずつ足していって、大きい方の数字と等しくならない限り続けるように作ったつもりなのですが・・・ どこがおかしいのか教えて頂けると嬉しいです。 それとワガママなお願いなのですが、できれば、正答のようなものは書かないでもらえると助かります、どこが間違いなのかだけ教えて頂いて、後はなんとか自分の力でこなしてみたいので・・・ 自分勝手なお願いですが、よろしくお願いします。

  • C言語初心者です。次のプログラムを簡潔にしたいです

    二つの整数値を読み込んで、小さい方の数以上で大きい方の数以下の整数を全て加えた値を表示するプログラムを作成せよ。 自分のプログラムは以下の通りです。 #include <stdio.h> int main(void) { int num1,num2,small,big,sum=0; printf("二つの整数を入力してください。\n"); printf("整数A:"); scanf("%d",&num1); printf("整数B:"); scanf("%d",&num2); small=(num1 > num2) ? num2 : num1; big=(num1 > num2) ? num1 : num2; printf("%d以上%d以下の全整数の和は",small,big); if (num1 < num2) { do { sum+=num1; num1++; }while (num1 <= num2); } else { do { sum+=num2; num2++; }while (num2 <= num1); } printf("%dです。",sum); return 0; } 結果は正しく表示されるはずです。 しかし多変数かつループ文を組み合わせているため、長ったらしくなっています。 どのようなプログラミングならば、簡潔にかけますか? 解答がないので困っています。

  • C言語の勉強でわからないところがあります。

    最近C言語の勉強を始めたのですが明解C言語入門編の演習4-3でうまくいかなくて困っています。 二つの整数値を読み込んで、小さい方の数以上で大きい方の数以下の整数を全て加えた値を表示するプログラムを作成するものなのですが、うまく起動しません。 まだ勉強を始めたばかりの自分が作ったものなので、つまらないミスや勘違いからでてきたエラーだと思うのですが、見て頂けると嬉しいです。 プログラムは以下の通りです。 #include <stdio.h> int main(void) { int n1,n2; int num=n1; int sub=n2; puts("二つの整数を入力してください"); printf("整数1:"); scanf("%d",&n1); printf("整数2:"); scanf("%d",&n2); printf("%d以上%d以下の全整数の和は", n1>n2 ? n1,n2:n2,n1); do{ if (n1>n2) num=n1+sub; sub=sub+1; printf("%d",num); else sub=n2+num; num=num+1; printf("%d",sub); }while(sub==n1 || num ==n2); return 0; } とすると、「22行目」で記述エラーを発見しました。 「identifier」を付け忘れています。となり、起動されることができません。 elseの文を削除すれば動作するのですが、37,28と入力した場合、1638137と大きすぎる数になってしまいます。 そこで二つ質問があります。 一つ目は、「22行目」で記述エラーを発見しました。 「identifier」を付け忘れています。といったものは、具体的に何処が間違っているのか、です。 二つ目は、何故else文を削除した場合のプログラムで、大きすぎる数になってしまうのかが知りたいのです。 この形に拘らずに組むのもいくつか思い浮かぶのですが、何故この形では動かないのかを知りたいので、間違っているところを指摘して頂けると嬉しいです。 そして、もし可能ならなのですが、正答のようなものは書きこまないで頂けると嬉しいです、間違っている理由だけを指摘して頂いて、なんとか後は自分で考えてみたくて・・・ ワガママな質問ですが、よろしくお願いします。

  • C言語のプログラミング (基礎)配列の問題ですが。

    次のような問題があって、プログラミングしてみたのですが、 コンパイルすると永久ループになってしまいます。 また、入力されるはずの整数が表示されません。 どうすればよいか教えていただけると助かります。 よろしくお願いします。 整数を順番に入力し、負の数が入力されたら、それまでに入力された非負の整数を、 入力された順番とは逆に全角空白で区切って出力するプログラムを作成しなさい。 自動評価の都合上、上記以外は表示しないこと。なお、入力は最大10回とする。 【0 1 2 3 4 -1 が入力された場合の表示例】 4 3 2 1 0       ************************************** #include <stdio.h> int main(void) { int num[10]; int n; for(n=1;n<11;n++){ printf("整数入力:¥n"); scanf ("%d", &num[n]); if(num[n]<0){ for(n=10;n>0;n--){ printf("%d ",num[n]); } } } }

  • C言語について  

    わからないのでよろしくお願いします。何回やってもうまく表示できません。 整数を入力し、入力された整数の数だけ「*」を横一列に表示し、最後に改行するプログラムを while 文を使って作りなさい。 但し、0または負の値が入力された場合は、「*」は表示せず、改行のみを表示すること。 ▼10が入力された場合の実行例 ********** #include<stdio.h> int main(void) { int n, kai; scanf("%d",&n); printf("\n nyuryoku=%d",n); while(0<kai){ kai=kai--; printf("*"); } kai=n; printf("\n"); }

  • c言語について

    C言語で、二つの整数値を読み込んで、前者の値が後者の何%であるかを実数で表示するプログラムを作成しようとして以下のコードを書きました。 #include <stdio.h> int main(void) { int n1, n2 ; puts("二つの整数を入力してください。") ; printf("整数A : \n") ; scanf("%d" , &n1) ; printf("整数B : \n") ; scanf("%d" , &n2) ; printf("Aの値はBの%f%%です。\n" , (double)(n1 / n2) * 100) ; return 0 ; } 上記コードを実行すると、0.000000%のような結果になります。 そこで、最後のキャスト演算子を使用した後の式で(n1 / n2) * 100がまずいのかなと考え、n1 / n2 * 100にしたら上手くいきました。 なぜ、上記コードだと上手くいかないんでしょうか?

  • C言語のプログラミング (基礎)教えてください。

    以下のような問題があります。 プログラムを作ってみたのですが、 コンパイルすると無限ループになったり、 正しく結果が出ません。 どのように直せば良いか教えていただけると助かります。 よろしくお願いします。 整数が入力される度に今までの合計を出力するプログラムを作成しなさい。なお、0 が入力されたら終了するものとする。 ただし、繰り返しの命令は while 文を使用し、条件は常に真 ( 1 ) とし、break 文を使うこと。 ▼実行例 整数:1     合計:1 整数:2     合計:3 整数:3     合計:6 整数:0 ******************************** #include<stdio.h> int main(void) { int n,sum; sum=0; while(1){ printf("¥n整数:"); scanf ("%d", &n); sum=sum+n; printf("¥n    合計:%d", sum); scanf ("%d", &sum);          if(n==0){ break;   } } }

  • C言語でのプログラミングの問題が分かりません。

    C言語でのプログラミングの問題が分かりません。 課題で出た問題なのですがわからないのでおしえてください。 問題は 値を入力します(nとします) nが1でない間、以下の処理を繰り返します。  (1)nが偶数のとき、nを2で割り、その答えを新しいnとします。  (2)nが奇数のとき、nを3倍してから1を加え、その答えを新しいnとします。 というものです。 if文を使い計算はできたのですが、「繰り返し」と「新しいnとする」部分が分かりませんでした。作成したプログラムを載せるので手直しお願いいたします。 int n,x,y; printf("整数を入力"); scanf("%d",&n); while (n>1) if (n%2) printf("%d",x=n*3+1); else printf("%d",y=n/2); putchar('\n'); return(0); です。このままだと無限ループしてしまうので繰り返しの条件が悪いみたいです。 それと、答えをnに入れたいのにx、yを使ってしまっています。 回答お願いします。

  • c言語超初心者です。教えてください

    基本的だと思いますが教えてください。 #include <stdio.h> int main(void) { int na, nb: puts("二つの整数を入力してください."); printf("整数A:”); scanf("%d",&na); printf("整数B:”); scanf("%d",&nb); printf("それらの平均は%fです。\n,(na+nb)/2.0); return(0); } これでintの形で最後のprintfが%fなのですがintは%dとなるはずなのですがこれは2。0という実数値で割るから答えは実数値になりますよ。という意味で%fとしたのでしょうか?確かにこうしないと正しい値がでてこないのです。教えてください。

専門家に質問してみよう