二次方程式の解と一次元配列
二次方程式の解と一次元配列
こんにちは。いつもお世話になっております。
学校の課題で
「2 次方程式 x2 + ax + b = 0 の実数解を求め,画面表示するプログラムを作成しなさい.ただし,
以下に示した条件を満たすこと.
係数a,b の条件: 実数型とし,キーボードから入力させること.
関数の条件: プロトタイプ: int solve( float, float, float *, float * )
第1 引数: x の係数 第2 引数: 定数項
第3 引数: 第1 解へのポインタ 第4 引数: 第2 解へのポインタ
返り値: 解の個数
画面表示の条件: 関数からの返り値を利用し,画面表示を適切に変化させること.
平方根を計算するためには,関数「double sqrt(double)」を使用することができる.ただし,プログラ
ムの冒頭に「#include math.h」と記述し,コンパイルオプションとして「-lm」を指定すること」
というのと
「まず1 次元整数型配列(配列名data,要素数は任意)を準備する.キーボードから任意個の整数デ
ータを入力させ,入力されたデータの ①最大値,②最小値,③平均,④標準偏差 を求めて画面表
示するプログラムを作成しなさい.ただし,上記の4 つの処理について,それぞれ下記の条件を満た
す関数を作成すること.
① 最大値: int max( int *, int )
第1 引数: 配列アドレス 第2 引数: データ数 返り値: 最大値
② 最小値: int min( int *, int )
第1 引数: 配列アドレス 第2 引数: データ数 返り値: 最小値
③ 平均: float average( int *, int )
第1 引数: 配列アドレス 第2 引数: データ数 返り値: 平均値
④ 標準偏差: float std_dev( int *, int )
第1 引数: 配列アドレス 第2 引数: データ数 返り値: 標準偏差」
というのが出たんですけど、今回、講義のほうを欠席してしまった関係で何をすればいいのか分かりません(>_<)
どなたかレクチャーお願いしますm(_ _)m 2つも課題丸投げになっちゃってすいません…。
学校の課題で
「2 次方程式 x2 + ax + b = 0 の実数解を求め,画面表示するプログラムを作成しなさい.ただし,
以下に示した条件を満たすこと.
係数a,b の条件: 実数型とし,キーボードから入力させること.
関数の条件: プロトタイプ: int solve( float, float, float *, float * )
第1 引数: x の係数 第2 引数: 定数項
第3 引数: 第1 解へのポインタ 第4 引数: 第2 解へのポインタ
返り値: 解の個数
画面表示の条件: 関数からの返り値を利用し,画面表示を適切に変化させること.
平方根を計算するためには,関数「double sqrt(double)」を使用することができる.ただし,プログラ
ムの冒頭に「#include math.h」と記述し,コンパイルオプションとして「-lm」を指定すること」
というのと
「まず1 次元整数型配列(配列名data,要素数は任意)を準備する.キーボードから任意個の整数デ
ータを入力させ,入力されたデータの ①最大値,②最小値,③平均,④標準偏差 を求めて画面表
示するプログラムを作成しなさい.ただし,上記の4 つの処理について,それぞれ下記の条件を満た
す関数を作成すること.
① 最大値: int max( int *, int )
第1 引数: 配列アドレス 第2 引数: データ数 返り値: 最大値
② 最小値: int min( int *, int )
第1 引数: 配列アドレス 第2 引数: データ数 返り値: 最小値
③ 平均: float average( int *, int )
第1 引数: 配列アドレス 第2 引数: データ数 返り値: 平均値
④ 標準偏差: float std_dev( int *, int )
第1 引数: 配列アドレス 第2 引数: データ数 返り値: 標準偏差」
というのが出たんですけど、今回、講義のほうを欠席してしまった関係で何をすればいいのか分かりません(>_<)
どなたかレクチャーお願いしますm(_ _)m 2つも課題丸投げになっちゃってすいません…。
Re:二次方程式の解と一次元配列
現状を整理する意味をこめて、まずは、
2つの問題について
・わかっていること
・わからないこと
を書き出してみましょう。
【例】
・2次方程式の解の公式はわかっている
・標準偏差の計算方法がわからない
2つの問題について
・わかっていること
・わからないこと
を書き出してみましょう。
【例】
・2次方程式の解の公式はわかっている
・標準偏差の計算方法がわからない
Re:二次方程式の解と一次元配列
じゃあ、まず1つめの課題の方から…。
「わかっていること」
・二次方程式の解を表示するだけのプログラム
・プロトタイプ宣言の仕方
「わからないこと」
・ポインタの使い方
・返り値について
・プロトタイプ宣言の中の[float *]はなんなのか。
考えられるのはこんな感じです。あとは何がわからないのか分からないのかも知れません。
「わかっていること」
・二次方程式の解を表示するだけのプログラム
・プロトタイプ宣言の仕方
「わからないこと」
・ポインタの使い方
・返り値について
・プロトタイプ宣言の中の[float *]はなんなのか。
考えられるのはこんな感じです。あとは何がわからないのか分からないのかも知れません。
Re:二次方程式の解と一次元配列
まだ全然書いてないんですけど…。とりあえず
#include<stdio.h>
#include<math.h>
int solve(float,float,float*,float*)
int solve(float a,float b,float* r1 ,float* r2)
{
double D;
D=a*a-4*b;
if(D>0){
*r1 = (-a + sqrt(D))/2;
*r2=(-a-sqrt(D))/2;
return2;
}
if(D==0){
*r1 = -a/2;
return 1;
}
if(D<0)
return -2;
}
if(a!=0){
*r1 = -c/b;
return 1;
}
if(b!=0)
return 0;
else
return -1;
と、まだメインのほうは書けてないんですけど、こんな感じです。こんな状態でもすでに間違いが
ある気がして情けないです。
#include<stdio.h>
#include<math.h>
int solve(float,float,float*,float*)
int solve(float a,float b,float* r1 ,float* r2)
{
double D;
D=a*a-4*b;
if(D>0){
*r1 = (-a + sqrt(D))/2;
*r2=(-a-sqrt(D))/2;
return2;
}
if(D==0){
*r1 = -a/2;
return 1;
}
if(D<0)
return -2;
}
if(a!=0){
*r1 = -c/b;
return 1;
}
if(b!=0)
return 0;
else
return -1;
と、まだメインのほうは書けてないんですけど、こんな感じです。こんな状態でもすでに間違いが
ある気がして情けないです。
Re:二次方程式の解と一次元配列
> int solve(float,float,float*,float*)
プロトタイプ宣言の最後に、セミコロンが必要です。
> if(D<0)
> return -2;
> }
> if(a!=0){
> *r1 = -c/b;
> return 1;
> }
> if(b!=0)
> return 0;
> else
> return -1;
solve関数の戻り値(実数解の個数)は、判別式Dの符号だけによって
決まります。引用した箇所で係数a, bを使う必要はありません。
プロトタイプ宣言の最後に、セミコロンが必要です。
> if(D<0)
> return -2;
> }
> if(a!=0){
> *r1 = -c/b;
> return 1;
> }
> if(b!=0)
> return 0;
> else
> return -1;
solve関数の戻り値(実数解の個数)は、判別式Dの符号だけによって
決まります。引用した箇所で係数a, bを使う必要はありません。
Re:二次方程式の解と一次元配列
> > if(D<0)
> > return -2;
> > }
> > if(a!=0){
> > *r1 = -c/b;
> > return 1;
> > }
> > if(b!=0)
> > return 0;
> > else
> > return -1;
>
> solve関数の戻り値(実数解の個数)は、判別式Dの符号だけによって
> 決まります。引用した箇所で係数a, bを使う必要はありません。
では、これらは記述する必要がないのですか?
すいません。やっぱりあまり分かってなかったみたいで…。
> > return -2;
> > }
> > if(a!=0){
> > *r1 = -c/b;
> > return 1;
> > }
> > if(b!=0)
> > return 0;
> > else
> > return -1;
>
> solve関数の戻り値(実数解の個数)は、判別式Dの符号だけによって
> 決まります。引用した箇所で係数a, bを使う必要はありません。
では、これらは記述する必要がないのですか?
すいません。やっぱりあまり分かってなかったみたいで…。
Re:二次方程式の解と一次元配列
> では、これらは記述する必要がないのですか?
大部分は。
D > 0 のとき、実数解は2個 → if文で return 2; している
D == 0 のとき、実数解は1個 → if文で return 1; している
D < 0のとき、実数解は何個ですか? return いくつ; にすればよいですか?
大部分は。
D > 0 のとき、実数解は2個 → if文で return 2; している
D == 0 のとき、実数解は1個 → if文で return 1; している
D < 0のとき、実数解は何個ですか? return いくつ; にすればよいですか?
Re:二次方程式の解と一次元配列
出題文で「返り値: 解の個数」となっています。
実数解が0個のときに返り値を-2にするのは、
出題文の趣旨と合っていますか?
他のサイトを参考にするのは一向にかまいません。
しかし、大前提は出題文に載っていることを忘れないでください。
実数解が0個のときに返り値を-2にするのは、
出題文の趣旨と合っていますか?
他のサイトを参考にするのは一向にかまいません。
しかし、大前提は出題文に載っていることを忘れないでください。
Re:二次方程式の解と一次元配列
では、このようになるのでしょうか?
#include<stdio.h>
#include<math.h>
int solve(float,float,float*,float*);
int solve(float a,float b,float* r1 ,float* r2)
{
double D;
D=a*a-4*b;
if(D>0){
*r1 = (-a + sqrt(D))/2;
*r2=(-a-sqrt(D))/2;
return2;
}
if(D==0){
*r1 = -a/2;
return 1;
}
if(D<0)
return 0;
}
そしてこの後はどうしていくべきなのでしょうか?
#include<stdio.h>
#include<math.h>
int solve(float,float,float*,float*);
int solve(float a,float b,float* r1 ,float* r2)
{
double D;
D=a*a-4*b;
if(D>0){
*r1 = (-a + sqrt(D))/2;
*r2=(-a-sqrt(D))/2;
return2;
}
if(D==0){
*r1 = -a/2;
return 1;
}
if(D<0)
return 0;
}
そしてこの後はどうしていくべきなのでしょうか?
Re:二次方程式の解と一次元配列
> return2;
returnと2の間に、1個以上の空白をあけてください。
今のままでは、コンパイル時にエラーが出ます。
> そしてこの後はどうしていくべきなのでしょうか?
main関数のコードを書いてください。
・必要な変数を定義する
・係数a, bを入力する
・solve関数を呼び出す
・solve関数の戻り値に応じた内容を出力する
returnと2の間に、1個以上の空白をあけてください。
今のままでは、コンパイル時にエラーが出ます。
> そしてこの後はどうしていくべきなのでしょうか?
main関数のコードを書いてください。
・必要な変数を定義する
・係数a, bを入力する
・solve関数を呼び出す
・solve関数の戻り値に応じた内容を出力する
Re:二次方程式の解と一次元配列
returnはうっかり凡ミスでした。すいません。
main関数内で書くことがいまいちわかりません。宣言した関数はメインプログラム内ではどのように用いるのですか?また返り値はどのように使いますか?
main関数内で書くことがいまいちわかりません。宣言した関数はメインプログラム内ではどのように用いるのですか?また返り値はどのように使いますか?
Re:二次方程式の解と一次元配列
下のコードが何をしているか、解読してみてください。
その後、実際に実行してください。
そして、解読結果と実行結果を比べてください。
その後、実際に実行してください。
そして、解読結果と実行結果を比べてください。
#include <stdio.h> int f(int m, int *n); int main(void) { int a, b, c; for (a = 1; a <= 3; a++) { c = f(a, &b); printf("a=%d, b=%d, c=%d\n", a, b, c); } return 0; } int f(int m, int *n) { *n = m * 100; return 2 * m + 1; }
Re:二次方程式の解と一次元配列
まずa=1のときはf関数の中のmにaの値1が代入される。そして*nの値が計算されてその解である100がbの値として格納される。また返り値2*m+1が計算されその解である3がcの値として格納される。以後、a=2,3の時も同様に考えて解読結果は
a=1,b=100,c=3
a=2,b=200,c=5
a=3,b=300,c=7
となりました。実行結果もこうなりました。読めはするんですけどいまいち使い方がわからないんです…。
a=1,b=100,c=3
a=2,b=200,c=5
a=3,b=300,c=7
となりました。実行結果もこうなりました。読めはするんですけどいまいち使い方がわからないんです…。
Re:二次方程式の解と一次元配列
「読めるけど書けない」という状況はプログラミングに限らず、
漢字の書き取りなど、よくある話ではあります。
この状況を抜け出すにはどうするか?
自分の頭と手を使ってひたすら書く以外にありません。
人が書いたコードを「見るだけ」では、自分で書けるようにはなりません。
授業で何かテキストを使っていて、それに練習問題が載っていれば、
解答を見ないでコードを書く練習を積んでみてください。
漢字の書き取りなど、よくある話ではあります。
この状況を抜け出すにはどうするか?
自分の頭と手を使ってひたすら書く以外にありません。
人が書いたコードを「見るだけ」では、自分で書けるようにはなりません。
授業で何かテキストを使っていて、それに練習問題が載っていれば、
解答を見ないでコードを書く練習を積んでみてください。
Re:二次方程式の解と一次元配列
少し頑張ってみました…。それで自分なりにプログラムを書いてみたんですけどわけわかんなくなっちゃいました。一応二次方程式の解は求められるんですけど課題文にだいぶ反している気がします。ちなみに今現在のプログラムはこうなっています。
#include<stdio.h>
#include<math.h>
int solve(float,float,float*,float*);
int main(void){
double D;
float a,b,r1,r2;
printf("xの係数を入力 ->");
scanf("%f",&a);
printf("定数項を入力 ->");
scanf("%f",&b);
r1=solve(&r1);
r2=solve(&r2);
printf("二次方程式の解は[%f]と[%f]です\n",r1,r2);
printf("二次方程式の解は[%f] 重解です\n",r1);
printf("二次方程式の実数解はありません\n");
return 0;
}
int solve(float m,float n,float* y1,float* y2){
double D;
D=m*m-4*n;
if(D>0){
*y1=(-m+sqrt(D))/2;
*y2=(-m-sqrt(D))/2;
return 2;
}
if(D==0){
*y1=-m/2;
return 1;
}
if(D<0)
return 0;
}
どうでしょうか?正直いろいろ間違っていて根本的に理解出来てないんだと思います……
#include<stdio.h>
#include<math.h>
int solve(float,float,float*,float*);
int main(void){
double D;
float a,b,r1,r2;
printf("xの係数を入力 ->");
scanf("%f",&a);
printf("定数項を入力 ->");
scanf("%f",&b);
r1=solve(&r1);
r2=solve(&r2);
printf("二次方程式の解は[%f]と[%f]です\n",r1,r2);
printf("二次方程式の解は[%f] 重解です\n",r1);
printf("二次方程式の実数解はありません\n");
return 0;
}
int solve(float m,float n,float* y1,float* y2){
double D;
D=m*m-4*n;
if(D>0){
*y1=(-m+sqrt(D))/2;
*y2=(-m-sqrt(D))/2;
return 2;
}
if(D==0){
*y1=-m/2;
return 1;
}
if(D<0)
return 0;
}
どうでしょうか?正直いろいろ間違っていて根本的に理解出来てないんだと思います……
Re:二次方程式の解と一次元配列
いつも最近返事が遅くなってしまってすみません。
頑張っていらっしゃいますね。
基本的に大きな間違いがいくつかありますけど、作成した関数の処理はほぼ正解でした。
最初からみていきましょう。ほとんど数値がfloatなので、計算はfloatに統一しました。
とりあえず最初の
double D;
は必要ないですね。次に
r1=solve(&r1);
ここは大きく違います。処理の構造をしっかり掴みましょう。
まず、solve(○);と書くと、○はどこにいきますか?
solve関数に処理がうつったとき、
int solve(float m,float n,float* y1,float* y2){
と書いた、それぞれのm,n,ya,y2に渡されます。
おかしいところがわかるでしょうか?
○つまり1つしか値を渡していないのに、solve関数の受け取る値である引数は4つになっています。
○はsolve関数に渡してやる変数ですから、4つ受け取るように指定しているなら4つ渡さないといけませんね。
今、a,b,y1,y2の変数を渡したいのですから、
solve(a,b,&y1,&y2);でないといけませんね。
ポインタの使い方がちゃんとなっていたのはすばらしいと思いましたが、受け取り方が間違っているので、たまたま書いた書き方があっていただけなのかな?受け取りについては☆1へ。
solve(a,b,&y1,&y2); と書いたとき、solve関数に処理がわたったとき、
int solve(float m,float n,float* y1,float* y2){
mにはaが、nにはbが、y1にはy1が、y2にはy2が入ります。
(ちなみに、受け取る値は無理にmやnといった変数名に変更しなくても、同じaやbでも使えます。)
☆1
返り値の受け取り方ですが
r1=solve(&r1);
これは間違いです。何が帰ってきているかに注目してください。
r1をポインタで渡したということは、r1にxの解の値を入れていることを期待しているのですよね。
r1でせっかくxの解、(例えば4.75234だとか)をいれたのに、後から返り値である
解の個数を入れてしまったのでは、計算した意味がありません。
return 2;
の2の意味がわかりますか?
main関数内でからsolve関数を呼んでいるとき、引数に5を指定しています。
solve関数ではその5を受け取り、mには5が入ります。
solve関数内で、mは10がたされ、15となり、mの値はreturnで帰ります。
returnで帰ってきた値は
a=solve(5);
のaに代入されます。
ですからprintfでは15が出力されるとわかりますね。
ではこのようなとき、
m自身がaと自身となり、mを変更することで、aも変更されます。
(だってデータを示している住所が同じもので、ただ変数名が違うだけだから。つまり示している先のデータは同じもの)
return でmの半分の値が返ります。
returnで返されたmの半分の値はbに格納されます。
処理の内容わかりますか?
つまり、solve関数で定義した解の個数を返すreturnは、受け取る時、解の個数を格納する変数にいれないといけないですね。
解の個数をnumという変数にいれるとすると
num=solve(a,b,&r1,&r2);
と書くことで、帰ってきた解の個数を格納できます。
printf("二次方程式の解は[%f]と[%f]です\n",r1,r2);
printf("二次方程式の解は[%f] 重解です\n",r1);
printf("二次方程式の実数解はありません\n");
これはご自分でもわかっていらっしゃるでしょうけど、毎回全部表示されてしまうのでダメですね。
それは「解の個数がどこにはいっているかわからない」から条件文がかけなかったんだと思います。
今はnumに解の個数が入っているので条件文がかけますね?
if文でもかけますが、ちょっといじってswitch文で書いてみました。
switch文も使ってみてください。
なお、solve関数内の計算部分は
float D;
*y1=(-m+sqrt(D))/2.0f;
このように全てフローとになるようにしてください。計算にint型、float型、double型が混合していましたので。
2.0fというのは2.0がfloat型ですよと明示的に言っているのです。
上記の事をしっかり見てから下のサンプルをみてください。
お書きになったプログラムを最大限生かしながら修正しました。
xの係数を入力 ->4.0
定数項を入力 ->3.0
二次方程式の解は[-1.000000]と[-3.000000]です。
よく確かめてないので計算結果がちゃんとあってるか、確かめてください。
どこかわからないところがあれば聞いてください。
頑張っていらっしゃいますね。
基本的に大きな間違いがいくつかありますけど、作成した関数の処理はほぼ正解でした。
最初からみていきましょう。ほとんど数値がfloatなので、計算はfloatに統一しました。
とりあえず最初の
double D;
は必要ないですね。次に
r1=solve(&r1);
ここは大きく違います。処理の構造をしっかり掴みましょう。
まず、solve(○);と書くと、○はどこにいきますか?
solve関数に処理がうつったとき、
int solve(float m,float n,float* y1,float* y2){
と書いた、それぞれのm,n,ya,y2に渡されます。
おかしいところがわかるでしょうか?
○つまり1つしか値を渡していないのに、solve関数の受け取る値である引数は4つになっています。
○はsolve関数に渡してやる変数ですから、4つ受け取るように指定しているなら4つ渡さないといけませんね。
今、a,b,y1,y2の変数を渡したいのですから、
solve(a,b,&y1,&y2);でないといけませんね。
ポインタの使い方がちゃんとなっていたのはすばらしいと思いましたが、受け取り方が間違っているので、たまたま書いた書き方があっていただけなのかな?受け取りについては☆1へ。
solve(a,b,&y1,&y2); と書いたとき、solve関数に処理がわたったとき、
int solve(float m,float n,float* y1,float* y2){
mにはaが、nにはbが、y1にはy1が、y2にはy2が入ります。
(ちなみに、受け取る値は無理にmやnといった変数名に変更しなくても、同じaやbでも使えます。)
☆1
返り値の受け取り方ですが
r1=solve(&r1);
これは間違いです。何が帰ってきているかに注目してください。
r1をポインタで渡したということは、r1にxの解の値を入れていることを期待しているのですよね。
r1でせっかくxの解、(例えば4.75234だとか)をいれたのに、後から返り値である
解の個数を入れてしまったのでは、計算した意味がありません。
return 2;
の2の意味がわかりますか?
#include <stdio.h> int solve(int m){ m = m+10; return m; } int main(){ int a; a=solve(5); printf("a=%d\n",a); return 0; }一度このプログラムの意味を考えましょう。
main関数内でからsolve関数を呼んでいるとき、引数に5を指定しています。
solve関数ではその5を受け取り、mには5が入ります。
solve関数内で、mは10がたされ、15となり、mの値はreturnで帰ります。
returnで帰ってきた値は
a=solve(5);
のaに代入されます。
ですからprintfでは15が出力されるとわかりますね。
ではこのようなとき、
#include <stdio.h> int solve(int *m){ *m = *m+10; return *m/2; } int main(){ int a,b; a=4; b=solve(&a); printf("a=%d,b=%d\n",a,b); return 0; }最初、aには4が入ります。aの変数の住所がsolve関数へ渡されます。aの住所ははmのポインタとなり、
m自身がaと自身となり、mを変更することで、aも変更されます。
(だってデータを示している住所が同じもので、ただ変数名が違うだけだから。つまり示している先のデータは同じもの)
return でmの半分の値が返ります。
returnで返されたmの半分の値はbに格納されます。
処理の内容わかりますか?
つまり、solve関数で定義した解の個数を返すreturnは、受け取る時、解の個数を格納する変数にいれないといけないですね。
解の個数をnumという変数にいれるとすると
num=solve(a,b,&r1,&r2);
と書くことで、帰ってきた解の個数を格納できます。
printf("二次方程式の解は[%f]と[%f]です\n",r1,r2);
printf("二次方程式の解は[%f] 重解です\n",r1);
printf("二次方程式の実数解はありません\n");
これはご自分でもわかっていらっしゃるでしょうけど、毎回全部表示されてしまうのでダメですね。
それは「解の個数がどこにはいっているかわからない」から条件文がかけなかったんだと思います。
今はnumに解の個数が入っているので条件文がかけますね?
if文でもかけますが、ちょっといじってswitch文で書いてみました。
switch文も使ってみてください。
なお、solve関数内の計算部分は
float D;
*y1=(-m+sqrt(D))/2.0f;
このように全てフローとになるようにしてください。計算にint型、float型、double型が混合していましたので。
2.0fというのは2.0がfloat型ですよと明示的に言っているのです。
上記の事をしっかり見てから下のサンプルをみてください。
お書きになったプログラムを最大限生かしながら修正しました。
#include<stdio.h> #include<math.h> int solve(float,float,float*,float*); int main(void){ int num; float a,b,r1,r2; printf("xの係数を入力 ->"); scanf("%f",&a); printf("定数項を入力 ->"); scanf("%f",&b); num=solve(a,b,&r1,&r2); switch(num){ case 0: printf("二次方程式の実数解はありません\n"); break; case 1: printf("二次方程式の解は[%f] 重解です\n",r1); break; case 2: printf("二次方程式の解は[%f]と[%f]です\n",r1,r2); break; default: printf("error\n"); break; } return 0; } int solve(float m,float n,float* y1,float* y2){ float D; D=(m*m-4*n); if(D>0){ *y1=(-m+sqrt(D))/2.0f; *y2=(-m-sqrt(D))/2.0f; return 2; } if(D==0){ *y1=-m/2.0f; return 1; } if(D<0) return 0; }実行例
xの係数を入力 ->4.0
定数項を入力 ->3.0
二次方程式の解は[-1.000000]と[-3.000000]です。
よく確かめてないので計算結果がちゃんとあってるか、確かめてください。
どこかわからないところがあれば聞いてください。
Re:二次方程式の解と一次元配列
わかりやすいご説明ありがとうございます。一度読んでみてだいぶ理解できたと思うのでもう一度読み返してみてわからないところがあればまた質問させていただきますね。
ところで問題文に「double sqrt(double)を使うことができる」とありますがこれはどういった意味でどのように使うのでしょうか?
ところで問題文に「double sqrt(double)を使うことができる」とありますがこれはどういった意味でどのように使うのでしょうか?
Re:二次方程式の解と一次元配列
> ところで問題文に「double sqrt(double)を使うことができる」とありますがこれはどういった意味でどのように使うのでしょうか?
solve関数の中で、判別式の平方根を求めるときに使ってますよね。
sqrtは「SQuare RooT」の略です。
引数がdouble型で、戻り値もdouble型です。
プロトタイプ宣言はmath.hに書いてあります。
だから、sqrt関数を使うときにはmath.hのインクルードが必要です。
solve関数の中で、判別式の平方根を求めるときに使ってますよね。
sqrtは「SQuare RooT」の略です。
引数がdouble型で、戻り値もdouble型です。
プロトタイプ宣言はmath.hに書いてあります。
だから、sqrt関数を使うときにはmath.hのインクルードが必要です。
Re:二次方程式の解と一次元配列
sqrtのプロトタイプ宣言はmath.hに書いてあるのでプロトタイプ宣言をする代わりにmath.hをインクルードするという事ですか?
あと、math.hをインクルードした場合、コンパイル時に-lmを渡すのはどういう意味ですか?
あと、math.hをインクルードした場合、コンパイル時に-lmを渡すのはどういう意味ですか?
Re:二次方程式の解と一次元配列
> sqrtのプロトタイプ宣言はmath.hに書いてあるのでプロトタイプ宣言をする代わりにmath.hをインクルードするという事ですか?
math.hの中に、sqrt関数や他の数学関数(三角関数、指数・対数関数など)の
プロトタイプ宣言が書いてあります。
#include <math.h>
と書けば、自分で
double sqrt(double);
と書かなくてもよいのです。
> あと、math.hをインクルードした場合、コンパイル時に-lmを渡すのはどういう意味ですか?
授業で利用している開発環境では、数学関数用のライブラリが
他の標準関数用のライブラリとは別のファイルになっているのでありましょう。
そういう環境では、数学関数を使うプログラムを書く場合、
・ソースに#include <math.h>と書く
・コンパイル時に-lm(lはリンクLinkの頭文字、mは数学Mathematicsの頭文字)の
オプションを指定することで、数学関数用のライブラリを使うことをコンパイラに知らせる
の2点が必要です。
math.hの中に、sqrt関数や他の数学関数(三角関数、指数・対数関数など)の
プロトタイプ宣言が書いてあります。
#include <math.h>
と書けば、自分で
double sqrt(double);
と書かなくてもよいのです。
> あと、math.hをインクルードした場合、コンパイル時に-lmを渡すのはどういう意味ですか?
授業で利用している開発環境では、数学関数用のライブラリが
他の標準関数用のライブラリとは別のファイルになっているのでありましょう。
そういう環境では、数学関数を使うプログラムを書く場合、
・ソースに#include <math.h>と書く
・コンパイル時に-lm(lはリンクLinkの頭文字、mは数学Mathematicsの頭文字)の
オプションを指定することで、数学関数用のライブラリを使うことをコンパイラに知らせる
の2点が必要です。
Re:二次方程式の解と一次元配列
なるほど。boxさん丁寧に教えて頂きましてありがとうございます。
管理人さんがswitch文で書いてくれたので自分はif文で書いてみました。プログラムはこれで大丈夫でしょうか?
#include<stdio.h>
#include<math.h>
int solve(float,float,float*,float*);
int main(void){
float a,b,r1,r2;
int num;
printf("xの係数を入力 ->");
scanf("%f",&a);
printf("定数項を入力 ->");
scanf("%f",&b);
num=solve(a,b,&r1,&r2);
if(num==2)
printf("二次方程式の実数解は[%f]と[%f]です\n",r1,r2);
if else(num==1)
printf("二次方程式の実数解は[%f] 重解です\n",r1);
if else(num==0)
printf("二次方程式の実数解はありません\n");
else
printf("error\n");
return 0;
}
int solve(float m,float n,float* y1 ,float* y2)
{
float D;
D=m*m-4*n;
if(D>0){
*y1 = (-m + sqrt(D))/2.0f;
*y2=(-m-sqrt(D))/2.0f;
return 2;
}
if(D==0){
*y1 = -m/2.0f;
return 1;
}
if(D<0)
return 0;
}
あと、一回メインプログラムの方に
else{
printf("error\n");
}
っていうのを入れてみたんですけど、実数解があるときにerrorも一緒に表示されてしまうんです。なにか間違っているんでしょうか?
管理人さんがswitch文で書いてくれたので自分はif文で書いてみました。プログラムはこれで大丈夫でしょうか?
#include<stdio.h>
#include<math.h>
int solve(float,float,float*,float*);
int main(void){
float a,b,r1,r2;
int num;
printf("xの係数を入力 ->");
scanf("%f",&a);
printf("定数項を入力 ->");
scanf("%f",&b);
num=solve(a,b,&r1,&r2);
if(num==2)
printf("二次方程式の実数解は[%f]と[%f]です\n",r1,r2);
if else(num==1)
printf("二次方程式の実数解は[%f] 重解です\n",r1);
if else(num==0)
printf("二次方程式の実数解はありません\n");
else
printf("error\n");
return 0;
}
int solve(float m,float n,float* y1 ,float* y2)
{
float D;
D=m*m-4*n;
if(D>0){
*y1 = (-m + sqrt(D))/2.0f;
*y2=(-m-sqrt(D))/2.0f;
return 2;
}
if(D==0){
*y1 = -m/2.0f;
return 1;
}
if(D<0)
return 0;
}
あと、一回メインプログラムの方に
else{
printf("error\n");
}
っていうのを入れてみたんですけど、実数解があるときにerrorも一緒に表示されてしまうんです。なにか間違っているんでしょうか?
Re:二次方程式の解と一次元配列
> 管理人さんがswitch文で書いてくれたので自分はif文で書いてみました。プログラムはこれで大丈夫でしょうか?
正しく動きます。
> っていうのを入れてみたんですけど、実数解があるときにerrorも一緒に表示されてしまうんです。なにか間違っているんでしょうか?
どこに入れたときですか?
正しく動きます。
> っていうのを入れてみたんですけど、実数解があるときにerrorも一緒に表示されてしまうんです。なにか間違っているんでしょうか?
どこに入れたときですか?
Re:二次方程式の解と一次元配列
> どこに入れたときですか?
メインプログラムのif文の最後です。
if(num==2)
printf("二次方程式の実数解は[%f]と[%f]です\n",r1,r2);
if(num==1)
printf("二次方程式の実数解は[%f] 重解です\n",r1);
if(num==0)
printf("二次方程式の実数解はありません\n");
else{
printf("error\n");
}
return 0;
}
という風にしてみたんですけど…。
メインプログラムのif文の最後です。
if(num==2)
printf("二次方程式の実数解は[%f]と[%f]です\n",r1,r2);
if(num==1)
printf("二次方程式の実数解は[%f] 重解です\n",r1);
if(num==0)
printf("二次方程式の実数解はありません\n");
else{
printf("error\n");
}
return 0;
}
という風にしてみたんですけど…。
Re:二次方程式の解と一次元配列
> if(num==0)
> printf("二次方程式の実数解はありません\n");
> else{
> printf("error\n");
> }
この場合、elseに来るのは、numが0でない場合です。
numは0か1か2の値をとりますから、numが1か2の場合、
つまり実数解がある場合にelseのところへ来てしまい、
"error"と表示します。
これを防ぐには、
elseを追加します。
こうすることで、numが2でも1でも0でもない、想定外の値になったときだけ
"error"と表示します。
> printf("二次方程式の実数解はありません\n");
> else{
> printf("error\n");
> }
この場合、elseに来るのは、numが0でない場合です。
numは0か1か2の値をとりますから、numが1か2の場合、
つまり実数解がある場合にelseのところへ来てしまい、
"error"と表示します。
これを防ぐには、
if(num==2) printf("二次方程式の実数解は[%f]と[%f]です\n",r1,r2); else if(num==1) printf("二次方程式の実数解は[%f] 重解です\n",r1); else if(num==0) printf("二次方程式の実数解はありません\n"); else{ printf("error\n"); }のように、numと1との判定、numと0との判定のところに
elseを追加します。
こうすることで、numが2でも1でも0でもない、想定外の値になったときだけ
"error"と表示します。
Re:二次方程式の解と一次元配列
おはようございます。
else文は、直前のif文に対応します。
つまり3つめのif文に入らない条件は全てelseになってしまいます。
1のifでもなく2のifでもなく、3のifでもないとき、elseにしたいときは
if
else if
else if
else
とかかないといけません。
elseはその他ですね。その他のとき、もし・・といった感じです。
else文は、直前のif文に対応します。
つまり3つめのif文に入らない条件は全てelseになってしまいます。
1のifでもなく2のifでもなく、3のifでもないとき、elseにしたいときは
if
else if
else if
else
とかかないといけません。
elseはその他ですね。その他のとき、もし・・といった感じです。
Re:二次方程式の解と一次元配列
あ、御回答中だったのですね^^; ありがとうございます、すみません^^;
そういえばsqrtの返り値がそろってないですね。
sqrtfを使った方がいいように思いますが、問題文はdoubleを使うように成っています。
先生のミスなんでしょうか?なんでわざわざfloatやdoubleが混合するようにするんでしょうね。。
問題文にsqrtを使えと書いてあるので、それを使うなら
(float)でfloat型にdouble型の返り値を変換した方がいいと思います。
平方根を求める関数はその型に応じて、3つあります。
#include <math.h>
double sqrt(double x);
float sqrtf(float x);
long double sqrtl(long double x);
今回sqrtfを使った方がスムーズにいくはずですが、sqrtを使えと書いてあるので、その返り値をfloatに変換してください。
ちょっと長くなってしまったので、2つ目の質問をするときは、コピーペーストでいいので新しいトピをたててもらえますか?
この問題は最後までここに投稿してもらって大丈夫ですので。
よろしくお願いしますm(_ _)m
そういえばsqrtの返り値がそろってないですね。
sqrtfを使った方がいいように思いますが、問題文はdoubleを使うように成っています。
先生のミスなんでしょうか?なんでわざわざfloatやdoubleが混合するようにするんでしょうね。。
問題文にsqrtを使えと書いてあるので、それを使うなら
(float)でfloat型にdouble型の返り値を変換した方がいいと思います。
平方根を求める関数はその型に応じて、3つあります。
#include <math.h>
double sqrt(double x);
float sqrtf(float x);
long double sqrtl(long double x);
今回sqrtfを使った方がスムーズにいくはずですが、sqrtを使えと書いてあるので、その返り値をfloatに変換してください。
ちょっと長くなってしまったので、2つ目の質問をするときは、コピーペーストでいいので新しいトピをたててもらえますか?
この問題は最後までここに投稿してもらって大丈夫ですので。
よろしくお願いしますm(_ _)m
Re:二次方程式の解と一次元配列
あ~elseはそういう風に使うんですね。一つのifにしか対応してないとは…すっかり忘れてました。
sqrtをdouble型にするとどこがどのように変わるんですか?
sqrtをdouble型にするとどこがどのように変わるんですか?
Re:二次方程式の解と一次元配列
> sqrtをdouble型にするとどこがどのように変わるんですか?
一般に、float型は4バイト、double型は8バイトの領域をとります。
領域が大きいほど、扱える値の範囲が広くなります。
一般に、float型は4バイト、double型は8バイトの領域をとります。
領域が大きいほど、扱える値の範囲が広くなります。
Re:二次方程式の解と一次元配列
boxさん、ありがとうございます。
管理人さん。2つめの質問は新しくトピをたてさせてもらいます。すごく長いトピになってしまって
すいませんでした。おそらく最後の質問になると思うんですが・・・返り値をfloat型に変換とはどのようにやるのですか?
管理人さん。2つめの質問は新しくトピをたてさせてもらいます。すごく長いトピになってしまって
すいませんでした。おそらく最後の質問になると思うんですが・・・返り値をfloat型に変換とはどのようにやるのですか?
Re:二次方程式の解と一次元配列
いえいえ、別に一つの質問で話が長くなる文には全然問題ないですよ。
ただ一つのトピでいくつも話題・問題があると、題名と異なる内容になったりして、
閲覧者が混乱したりしてはいけないと思っているだけなので、
特に深くお考えにならないでください。
1トピ、1質問 =閲覧者が見やすい
そう思っているだけですので。
floatの変換は上記私のプログラムを参考にしてください。
(float)と書くことで、変換できます。
ただ一つのトピでいくつも話題・問題があると、題名と異なる内容になったりして、
閲覧者が混乱したりしてはいけないと思っているだけなので、
特に深くお考えにならないでください。
1トピ、1質問 =閲覧者が見やすい
そう思っているだけですので。
floatの変換は上記私のプログラムを参考にしてください。
int a=3,b=2; float c; c=a/b; ‥① c=(float)a/(float)b; ‥②①の計算結果は1ですが、②の計算結果は1.5です。
(float)と書くことで、変換できます。