質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

while

Whileは多くの言語で使われるコントロール構造であり、特定の条件が満たされる限り一連の命令を繰り返し実行します。

Q&A

解決済

3回答

834閲覧

for文で書いたプログラムをwhile文に書き換えたがうまく実行されない際の解決策について

lix

総合スコア1

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

while

Whileは多くの言語で使われるコントロール構造であり、特定の条件が満たされる限り一連の命令を繰り返し実行します。

0グッド

1クリップ

投稿2021/06/02 07:07

編集2021/06/02 07:53

for文をwhile文に書き換えたい

C言語にてfor文で書いたプログラムをwhile文に書き換えたいです。

for文のソースコード

#include <stdio.h> #include <math.h> double Leibniz(int n){ double S; for (int i = 0; i <= n; i++) { if (i % 2 == 0) { S += (double)1 / (2 * i + 1); } else { S -= (double)1 / (2 * i + 1); } } S = S * 4; return S; } unsigned int main(void) { printf(" XXXXXXXXXXXXXXXXX\n\n"); for(int n = 0; n <=10000000000;n += 10000000) { if (Leibniz(n)-M_PI <= 0.00000001){ break; } printf(" 計算結果は %.15f\n\n", Leibniz(n)/5); printf(" 項数は %d\n\n", n); printf(" 誤差は %17.15f\n\n", Leibniz(n)-M_PI); } return 0; }

追記質問

下の方にprintf(" 計算結果は %.15f\n\n", Leibniz(n)/5);
とありますがなぜかここの実行結果が求めたい結果の5倍になってしまいます。
なので/5をプログラムに追加していますが、どのように改善したら5倍されずに本来求めたい計算結果が得られるのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

1T2R3M4

2021/06/02 07:09

作業依頼ですか。
lix

2021/06/02 07:14

すみません。 自分のwhile文に書き換えたソースコードの載せるのを忘れていました。 while文に関して詳しくなく、無茶苦茶なソースコードになっているので どこをどのように書き換えればうまく実行できるのか教えて頂きたいと思っております。 自分の書き換えたソースコード↓ #include <stdio.h> #include <math.h> double Leibniz(int n){ double S; int i = 0; while(i <= n) { if (i % 2 == 0) { S += (double)1 / (2 * i + 1); } else { S -= (double)1 / (2 * i + 1); i++; } } S = S * 4; return S; } unsigned int main(void) { printf(" XXXXXXXXXXXXXXXXXXXXXX\n\n"); int n = 0; while(n <=10000000000) { if (Leibniz(n)-M_PI <= 0.00000001){ break; } printf(" 計算結果は %.15f\n\n", Leibniz(n)/5); printf(" 項数は %d\n\n", n); printf(" 誤差は %17.15f\n\n", Leibniz(n)-M_PI); n += 10000000; } return 0; } 恐らくかなり無茶苦茶なソースコードだとは思いますが改善点等あればよろしくお願いいたします。
kaina

2021/06/02 07:18

せめて何を行うプログラムか位、書いたほうが良いと思いませんか? つじつま合わせで5分の1をしないと求める結果が出力されないプログラムから 何をする為のプログラムなのかの解析を含めて回答者に求めるのですか? 後、for文からwhile文に書き換えることの何が分からないか具体的に書いて下さい。 でないと、1T2R3M4さんの言う通りただの作業依頼ですよ。
dodox86

2021/06/02 07:21

for文もwhile文も大差ありません。 (1) for文 int i; for (i = 0; i < 10; i++) { ; /* hoge */ } は (2) while文 int i = 0; while (i < 10) { ; /* hoge */ i++; } と同じです。ご提示のコードは読んでいませんが、問題は別のところにあるのではないですか?
lix

2021/06/02 07:38

行う内容は適当な関数を自分で設定し(この場合は有名な(-1)^n/(2n+1)をπに近づくまで試しに求めています)それをfor文やwhile文を用い正確に計算するプログラムを作りたいです。 また、for文からwhile文に書き換える際にわからない事はdodox86様から回答いただいてる通り、 for(式1;式2;式3)となっているソースコードを 式1; while(式2){反復実行したい部分 式3;}と書き換えているにも関わらずプログラムが正常に実行されない所です。
lix

2021/06/02 07:40

dodox86様 ご返信ありがとうございます。 その様に書き換える事は理解しているのですが、その様に書き換えても正常に動作しないのでなぜなのかわからない状態です。
dodox86

2021/06/02 07:44

私が何を伝えたいのかと言いますと、質問の件名にあるような「for文で書いたプログラムをwhile文に書き換えたい」と言うことは本筋の解決策にならないでしょう、ということです。件名だけを読むと、まさにその部分だけを書き換えれば回答は終わりです。
lix

2021/06/02 07:51

確かに書き換えたいだけですと、自分の書いたプログラムがすでに書き換えが済んでいます。 質問文を変更して改めて質問したいと思います。 ありがとうございます。
mikanlemon

2021/06/02 08:00

ぱっと見なんでよくわからんですけどwhileの中にreturnがあるから正しく動作してないんじゃないですかね?
退会済みユーザー

退会済みユーザー

2021/06/02 08:09 編集

そもそも、ちゃんとデバッグしていますか? ループ中の変数の値をデバッガでステップ実行して確認したり、出力してみたりすれば、どこで想定外の値になったかすぐ判ると思うんですが。課題か何か知りませんけど、人からもらったコード提出するだけなら何も身に付かないですよ?
lix

2021/06/02 08:20

radian様 書き込みありがとうございます。 まだC言語、プログラミングに関して無知中の無知なのでステップを踏んで実行しても自分一人の力ではどこが問題なのか分からないから質問させて頂いてます。 あと、別に課題では無いですし他人からソースコードを貰うなら友人から貰えば済む話ですよね? そういうつもりで自分が質問している訳ではなく、作りたいプログラムの中で躓いた点がありそこを本質的に教えて頂きたいので質問させて頂いています。 最後のその一文は少し失礼では無いですか?
退会済みユーザー

退会済みユーザー

2021/06/02 08:33 編集

> そういうつもりで自分が質問している訳ではなく、作りたいプログラムの中で躓いた点がありそこを本質的に教えて頂きたいので質問させて頂いています。 それなら、どこで躓いたか具体的に書いた方が良くないですか?単なる投げっぱなしの質問のように見えるので、他の方にも作業依頼と指摘を受けていますよね。 プログラムはあなたの書いた通りに動くだけなので、動きがおかしいなら途中の変数の値を出力してみれば良くないですか?for文では出来ているんですよね?whileに変えた時に比較したらすぐ判るんじゃないですか?
lix

2021/06/02 08:39

radian様 最初その様な指摘を受け、ここの質問欄や質問文を変え自分のプログラムに関しての回答を頂きました。 先程も申しました通りプログラミング初心者でどこで躓いたかもradian様のように知識がないのでfor文が上手くWhile文に変更できない。程度にしか具体的な説明が出来ません。 それと、何故初心者マークまでつけて、内容も変更して質問しているにも関わらず、そこまで高圧的に対応されるのか理解できません。
kaina

2021/06/02 08:44

今回の質問の場合、私なら最初に以下のような内容を書いて質問します。 次回質問する際の参考にして下さい。 ライプニッツの公式からπ(パイ)を求めるプログラムをC言語のfor文を使用して 作成しましたが、for文をwhile文を使用したプログラムに書き換えたいです。 以下のようにfor文のプログラムをwhile文に変更してみましたが、 以下の通りfor文で実行した結果とは異なる結果が出力されてしまいます。 どの部分が間違っているかご指摘お願いします。 以下にfor文プログラムとwhile文のプログラムと それぞれの実行結果を記述
退会済みユーザー

退会済みユーザー

2021/06/02 08:47 編集

で、結局デバッグはしたんでしょうか?そもそもデバッグ依頼的な質問はteratailでは非推奨質問なんですが。 [推奨していない質問] https://teratail.com/help/avoid-asking
lix

2021/06/02 08:54 編集

kaina様 次回質問する際に自分の書いたプログラムと実行結果、及び回答者様が何が分からないかわかりやすい質問文を作成するように心がけてみます。 ありがとうございます。
lix

2021/06/02 09:01

radian様 ですから、デバッグ依頼でもないし、今回初めてで色々と至らない点があったと自覚して先の方からご指摘があり改善して質問内容も変更させていただいてます。 あなたは私に何かされたんですか?私に対する文句としか捉えられない文章ばっかり送り付けてきて何がしたいのかよくわからないので、これ以上返信してくるのはやめてください。 こちらが色々改善しながら初めての質問で至らない点もあったと思いますが、そのような事も加味出来ずに高圧的な内容を送られるのであればあなたも十分人としておかしな行為を行ってますよ。 もうあなたに返信するのも見るのも面倒くさいので通報するなり、なんなりお好きにしてください。迷惑です。
fana

2021/06/02 09:47

別に戦ってるわけじゃないのだから…… 「デバッグ依頼」に見えてしまう形になってしまった件に関しては, 「初心者故にどうやってデバッグしていけば良いのかが把握できていなかったが故に,質問を行うよりも前の段階では自分でそのような有効な方法による確認をできていなかった」みたいな話ならば,そう述べればとりあえず事情は伝わるでしょう. で,質問後に得られたコメントには幸運にもデバッグ方法に関する情報が多分に含まれているので,それをちゃんと拾って,実際に自身でやってみることが大切. 答えだけを得られたからBA選んで終わり!としてしまうならば,まさに「デバッグ作業丸投げ」となる.
lix

2021/06/02 10:48

fana様 仰る通りです。 答えを得られてBA選んで終わってしまっては、デバッグ作業丸投げとなってしまいます。 今回は幸運にもradian氏を除き質問の仕方やその他 注意点を丁寧に教えて下さる方がいらっしゃったのでその方達の説明を基に今後不明な点があれば質問して行きたいと思ってます。 また、頂いた回答にも自分の為となることが盛りだくさんでしたので全て実行させて頂き知識を深めることが出来たと思ってます。 どうも、戦ってるようなお見苦しい場面を見せてしまい申し訳ありません。
fana

2021/06/02 11:27

例えば「ご助言に従ってステップ実行して見ているとこんなことになってたんだけど,つーことは,これは○○ってことであってますかね?」とか何とか応答返したりすれば,孤立無援よりもマシな状態でデバッグ作業に臨めるかもしれない(?)し, せっかく有益情報込みの指摘が入ってるんだから,うまいことやるといいよね.せっかく労力かけて質問してるんだし.
guest

回答3

0

ベストアンサー

他の方の指摘されていない部分を指摘します。
Leibniz関数の変数Sの初期化がされていない為、
正しい結果が得られないので、
double S = 0.0;
として初期化しましょう。

以下のようなワーニングが出てませんか?
Main.c:10:13: warning: variable 'S' is uninitialized when used here [-Wuninitialized]

投稿2021/06/02 08:08

編集2021/06/02 08:10
kaina

総合スコア418

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lix

2021/06/02 08:23

ご回答ありがとうございます。 Ubuntuをコンパイルとして使用しているのですが、kaina様の仰るエラーは吐かれず、全く無関係な計算結果が実行されるだけです。 なので、完全に関数Sが初期化されていないという点には着目出来ていませんでした。 一度復習しつつ関数の初期化を試みてみます。 ありがとうございます。
kaina

2021/06/02 08:34

エラーでは無く、ワーニングです。 コンパイラが何か分かりませんが、コンパイル時にワーニングも出力するコンパイルオプションを 付けて下さい。 ついでに確認ですが、5倍の結果になるというのはfor文の場合ですか?while文の場合ですか? 私が確認した限り、for文の場合、初回の結果以外は正しい計算結果になりましたよ。
lix

2021/06/02 08:43

ワーニングでしたか…失礼しました。 一度コンパイラにワーニングも出力する様に設定してみたいと思います。ありがとうございます。 5倍の結果ですが、for文、while文共に何故か5倍になってしまいます… 恐らく私の貼ったソースコードのprintf(" 計算結果は %.15f\n\n", Leibniz(n)/5)に/5を入れているので正しく計算されるのですが、これを抜いてしまうと求めたい計算結果の5倍となってしまいます。 何故5倍になるのか全く分からず 勝手に5分の1をしてしまうという暴挙に出てしまっています…
退会済みユーザー

退会済みユーザー

2021/06/02 09:02

> 5倍の結果ですが、for文、while文共に何故か5倍になってしまいます… Wandboxで確認してみましたが、if内の呼び出し時の結果がSに残っており、 それが足された状態で4倍しているので、結果として5倍の数字が返っているようですね。 間に関数の呼び出しが入らないから、たまたま残っていたというところでしょうか。 まあ、未初期化踏んでる時点で、こちらの回答の通り、ちゃんと初期化しましょうとなるので、 細かいところまで調べる必要もありませんが。
lix

2021/06/02 09:19

userisgod様 関数の未初期化という自分のまだ勉強している範囲に及ばないことが影響を与えているとは全くもって考えられていませんでした。 あまりにも自分のプログラミングに関する知識が浅すぎて、ご迷惑をおかけするレベルな質の悪い質問でご迷惑をおかけしました。 今後は質問の仕方や知識、具体的内容を記載して質問したいと思います。 ありがとうございました。
guest

0

「質問への追記・修正の依頼」にあったコードをフォーマットし、
問題がありそうな箇所にコメントを追記しました。

c

1#include <stdio.h> 2#include <math.h> 3 4double Leibniz(int n) 5{ 6 double S; 7 int i = 0; 8 while (i <= n) 9 { 10 if (i % 2 == 0) 11 { 12 S += (double)1 / (2 * i + 1); 13 } 14 else 15 { 16 S -= (double)1 / (2 * i + 1); 17 18 // ここでインクリメントを行うと、elseの場合しか実行されない 19 i++; 20 } 21 } 22 S = S * 4; 23 return S; 24} 25 26unsigned int main(void) 27{ 28 printf(" XXXXXXXXXXXXXXXXXXXXXX\n\n"); 29 int n = 0; 30 while (n <= 10000000000) 31 { 32 if (Leibniz(n) - M_PI <= 0.00000001) 33 { 34 break; 35 } 36 printf(" 計算結果は %.15f\n\n", Leibniz(n) / 5); 37 printf(" 項数は %d\n\n", n); 38 printf(" 誤差は %17.15f\n\n", Leibniz(n) - M_PI); 39 n += 10000000; 40 } 41 return 0; 42}

投稿2021/06/02 08:00

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/06/02 08:01

かぶっとりますやんけ
lix

2021/06/02 08:30

userisgod様 ご回答ありがとうございます。 elseの{ }の中に与えたいプログラムを入力してしまうと、elseのみしか適用されない事を失念しておりました。 elseの{ }のあとにi++;を入力することで無事ifの場合elseの場合の両方に適用されfor文の時と同じく正しい実行結果が得られました。 初歩的なミスでしたが、今後も気をつけて行きたいと思います。 本当にありがとうございます。
guest

0

C

1double Leibniz(int n){ 2 double S; 3 int i = 0; 4 while(i <= n) { 5 if (i % 2 == 0) { 6 S += (double)1 / (2 * i + 1); 7 } else { 8 S -= (double)1 / (2 * i + 1); 9 i++; // ここ ? 10 } 11 } 12 S = S * 4; 13 return S; 14}

投稿2021/06/02 07:59

ozwk

総合スコア13521

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lix

2021/06/02 08:32

ozwk様 ご回答ありがとうございます。 userisgod様と同様の返信となってしまいますが、elseのみの適用となっているという初歩的な事でしたが、とてもスッキリしました。 何故 実行が上手くいかないのか…となった場合一度自分の入力したプログラムの場所が正しいか改めて確認していきたいと思います。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問