• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:C言語の問題でわからないところがあります)

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

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

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

  • ベストアンサー
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% (2173/4061)
回答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); などとして区切りをわかるようにした方がいいです。(カンマでもいいですが)