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

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

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

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

Q&A

解決済

1回答

2628閲覧

C言語 Simpson法 積分

KNTN

総合スコア25

C

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

0グッド

0クリップ

投稿2022/01/01 12:47

編集2022/01/01 13:15

プログラムについての質問です。 シンプソン法を用いて区間[0,1]でexpxを積分した値を求めるプログラムを作ろうとしているのですがエラーが出てしまっていてどの部分が間違っているのかわからないです。そしてこのプログラムについてですがEPSは分割数Nの場合と分割数2Nの場合の定積分値を比較しその差の絶対値がEPSよりも小さいときに定積分値の計算が終了しそれまでは分割数Nを二倍ずつ増加させる再帰的なプログラムとするためのものです。

C

1#include<stdio.h> 2 #include <math.h> 3 4double funk(double x); 5double simpson(double a, double b, int n, double (*f)()); 6 7int main(void) 8{ 9double *g; 10double EPS=*g; 11printf("sei no seisuu wo nyuuryoku ->",EPS); 12scanf("%d",EPS); 13 14printf("exp(x) wo [0,1] de sekibun simasu. bunkatu suu ha %d desu \n",2*EPS); 15printf("result is %20.15f\n",simpson(0, 1.0, EPS, funk)); 16return 0; 17} 18 19double simpson(double a, double b, int n, double (*f)()) { 20 21double S,h; 22int i; 23 24h=(b-a)/(2.0*n); 25 26S=((*f)(a)+(*f)(b)); 27 28for (i=1;i<n;i++) 29{ 30S += 4.0*(*f)(a+(2.0*i-1.0)*h)+2.0*(*f)(a+2.0*i*h); } 31 32S += 4.0*(*f)(a+(2.0*n-1.0)*h); S *= h/3.0; return S; 33} 34 35double EPS(double g) 36{ 37int n; 38 39*g = (simpson(0, 1.0, 2.0*n, funk)- simpson(0, 1.0, n, funk)); 40 41if(*g < EPS) 42 43return simpson(double a, double b, int 2.0*n, double (*f)()); 44 45else return 1; 46}

エラーメッセージ(コピペできなかったため写真を添付します)

イメージ説明
よろしくお願いします

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

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

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

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

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

y_waiwai

2022/01/01 12:48

このままではコードが読みづらいので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
y_waiwai

2022/01/01 12:49

エラーが出たなら、エラーメッセージを提示しましょう エラーメッセージは、いらぬ翻訳省略しないで、出たそのママをコピペで提示してください
KNTN

2022/01/01 13:03

teratailを初めて使用したため、使い方を十分に把握できていませんでした。申し訳ございません。
episteme

2022/01/01 15:03 編集

関数:EPS() がどこからも呼び出されていません。 関数:EPS() は再帰していません。
KNTN

2022/01/02 02:07

指摘ありがとうございます。 EPS()の再帰にする方法を教えていただきたいです。
episteme

2022/01/02 03:35 編集

再帰する必要あるんですか? 分割数を増やしながら繰り返すだけちゃいますの? そもそも呼ばれもしない関数定義して何の得があるんです?
KNTN

2022/01/02 03:56

なるほど、確かに指示は分割数を増やすだけで、ESPの値は固定です。上記のコードもESPは再帰ではないですよね?関数:EPS() がどこからも呼び出されていません。の詳細を詳しくお聞かせ願います。
episteme

2022/01/02 04:00

いや、main() の中に EPS() を呼んでるところがひとつもない。
kazuma-s

2022/01/03 13:22

> 区間[0,1]でexpxを積分した値を求める expx とは何ですか? コード中の funk とは何ですか? もしかすると、double funk(double x) { return exp(x); } ですか?
guest

回答1

0

ベストアンサー

エラーメッセージの意味が分からないのですか?

39行目の *gg は、35行目の double g ですから、型は double です。
単項演算子 * をポインタに適用して、演算結果がそのポインタの指すオブジェクト
になるべきなのに、「g がポインタではない」というエラーです。

41行目も同様。

43行目は関数simpson を呼び出して、返された値を return するつもりなのでしょうが、
関数呼出しの引数に書くのは、定数や変数や式などの値でなければなりません。
double a というのは値ではなく、宣言です。

次に、コードを main から見ていきます。

double *g; でポインタ変数 g を用意しましたが、初期化はしていないので
このポインタはどこを指しているのかまだ分かりません。

double EPS=*g; で doubleの変数 EPS を用意して、それをポインタ g が指す先の
double の値で初期化しようとしています。しかし、g はどこを指しているのか
分からないので、無意味な初期化です。

printf の第1引数の書式には "%d" や "%s" などの変換指定が無いので、
第2引数の EPS は無用です。

scanf の第1引数の書式の "%d" という変換指定は、第2引数に int * を要求します。
しかし、EPS は「int へのポインタ」ではなく、double です。

C のポインタが、全く理解できていないようです。
関数の宣言、関数の定義、関数の呼び出しも理解できていないようです。

追記
再帰ではなく、ループでやるとこんな感じでしょうか?

C

1#include <stdio.h> // printf 2#include <math.h> // fabs, exp 3 4#define EPS 1e-6 5 6double simpson(double a, double b, int n, double f(double)) 7{ 8 double h = (b - a) / (2 * n); 9 double s = f(a) + f(b); 10 for (int i = 1; i < n; i++) 11 s += 4 * f(a + (2 * i - 1) * h) + 2 * f(a + 2 * i * h); 12 s += 4 * f(a + (2 * n - 1) * h); 13 s *= h / 3; 14 return s; 15} 16 17int main(void) 18{ 19 int n = 1; 20 double y0 = simpson(0, 1, n, exp), y; 21 for (n = 2; ; n *= 2) { 22 //printf("n = %d, y0 = %f\n", n, y0); // 途中経過を見る 23 y = simpson(0, 1, n, exp); 24 if (fabs(y - y0) < EPS) break; 25 y0 = y; 26 } 27 printf("n = %d, y = %f\n", n, y); 28}

コメントをお願いします。

投稿2022/01/02 04:34

編集2022/01/03 16:02
kazuma-s

総合スコア8224

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

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

kazuma-s

2022/01/02 12:12

解決済みになっていますが、どのようなコードに修正したのですか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問