• ベストアンサー

C言語

毎度毎度お世話になります<(_ _)> 今回は関数のところで躓いています(;´Д`) 問題は二つなんですけど、 「二つの整数変数の引数の和を計算して結果を戻す関数plusを作成し、 それを利用して以下の実行結果になるようにしなさい。」 ■ 実行例 ■ Input two integer numbers 4 5 4+5=9 (数字は1例です) 「会場を求める関数factとべき乗を求める関数powintを利用して、 n!/xのn乗を求める関数pow_factを作成しなさい。 ただし、pow_fact関数は因数に整数値をとるが、戻り値は実数になることに注意しなさい。」 ■ 実行例 ■ Input number 5    1    1.000000000    2    0.500000000    3    0.222222224    4    0.093750000    5    0.038400002 ( 数字は1例です ) といった感じです。 最初の問題は int plus( int a, int b){ int y = 1; ココがわからない return y; } この先もわからない といった感じです。 二問目に関してはさっぱりわかってません(;´Д`) 回答、アドバイスなど沢山の回答お待ちしています。 ちなみにLinuxのGNOME端末をつかっています。

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

  • ベストアンサー
  • rentahero
  • ベストアンサー率53% (182/342)
回答No.9

1問目について 1:#include <stdio.h> 2: 3:int plus(int a, int b){ 4: int x = 1; 5: x=a+b; 6: return x; 7:} 8:int plus(int a,int b); 9:int main(void){ 10: int c,d; 11: printf("Input two integer numbers\n"); 12: scanf("%d %d\n",&c, &d); 13: printf("%d+%d=%d\n",c, d, plus(c,d)); 14: return 0; 15:} 行を説明しやすいように整形しました。 疑問点: 4行目、xを初期化しているのはなぜですか。 8行目、プロトタイプ宣言が関数実体より後ろにあるのはなぜですか。 12行目、scanfで改行を明示的に取得しているのはなぜですか。 このうち動作に直接関係あるのは12行目のみですが、4行目と8行目の件はC言語でプログラムを書くうえでのいわゆる「お約束」を正しく理解しているかどうかということでより深刻です。 ・必要のない初期化を行うと、後で読むときに妨げになるので、無意味な初期化は行わないようにするべきです。 ・プロトタイプ宣言は、関数実体より前に置くことで、関数実体がみつからなくても関数呼び出しを正しくコンパイルするためにあるものです。 scanfの問題は#7,#8の回答にあるとおりなのでここでは省略します。 2問目の分は、後ほど別に書きます。

すると、全ての回答が全文表示されます。

その他の回答 (9)

  • rentahero
  • ベストアンサー率53% (182/342)
回答No.10

2問目について 1:#include <stdio.h> 2:int powint(int, int); 3:int fact(int); 4:float pow_fact(int, int); 5:int main(void){ 6: int i, n; 7: printf("Input number\n"); 8: scanf("%d",&n); 9: for(i=1; i<=n; i++) 10: printf("%10d %20.9f\n",i,pow_fact(i,i)); 11:} 12:int powint(int a,int b){ 13: int pow=1,i=b; 14: while(i-->0) 15: pow*=a; 16: return pow; 17:} 18:int fact(int c){ 19: int j, fact; 20: fact=1; 21: for(j=1; j<=c; j++) 22: fact*=j; 23: return fact; 24:} 25:float pow_fact(int d,int e){ 26: float powfact=0; 27: powfact=(float)fact(d)/(float)powint(d,e); 28: return powfact; 29:} 行を説明しやすいように整形しました。 factとpowintについて 13~15行目、なぜwhileを使っているのですか。iの初期化を宣言時に行っているのはなぜですか。 上記と比較して 20~22行目、なぜforを使っているのですか。factとjの初期化を宣言時に行っていないのはなぜですか。 pow_factについて ・なぜ戻り値がdouble型ではなくfloat型なのですか。int型よりはるかに小さい有効数字でよいのでしょうか。というより、factやpowintの戻り値はint型でいいのでしょうか。複数回乗算を行う関数で戻り値にint型を使うのは、問題があります。linuxでは通常、intに32bit整数を使います。変数にintを使う限り、intの範囲に収まらない計算を行うことはできません。 ・実装されている式がd!/(d^e)になっているようですが、問題文ではn!/(x^n)だったのではありませんか。 もしくはn!/(n^n)だったのではありませんか。 もし前者であれば、d!/(e^d)であるべきだし、後者であれば、d!/(d^d)であるべきです。

Berabow
質問者

お礼

ご丁寧にありがとうございます<(_ _)> 指摘のあるところを改善ていきたいと思います。

すると、全ての回答が全文表示されます。
回答No.8

たしかに、 > scanf("%d %d\",&c, &d); が正解でしょう。 これは間違いですね。「消し忘れ」がありました。 でも、これは、注意してみたらわかるはずのところですよ。 > 質問文には記入し忘れていましたけど、 「powint fact pow_fact」の三つを 使いなさいと書いてありましたので使いました。 この3つを使うのは良いですよ。 ただし、使うのは、「powint と fact」の二つですよね。 pow_fact は、「作った」のですよね。 少なくとも、pow_fact は、 ・引数が不適切 ・powfact=(float)fact(d)/(float)powint(d,e); は正しくない のいずれか(あるいは両方)です。 pwoint と fact が、もともと作ってあったものだとしたら、それぞれ別の単元で作ったので、その単元の課題にあうように、わざわざ不自然な作り方をしたのかなとも思いますが、特に、powint は、かなり変な作り方の関数ですね。 あと、float を使うのも、そう習ったのでしょうか。 本当は、doble を使った方が良いのですけどね。

Berabow
質問者

お礼

floatは自分で決めて入力しました。汗 そういえばdobleは前勉強したのに全然使えてませんね↓ もっとスマートなプログラムが出来るように頑張ります<(_ _)> ありがとうございました。

すると、全ての回答が全文表示されます。
回答No.7

No. 1です。 プロトタイプ宣言とは? の人がいきなりこれでは、いかにもですね。 まず。 int powint(int a,int b) int fact(int c) float pow_fact(int d,int e) この引数の使い方、「関数の仮引数というものがわかってないな」という印象を持たれる可能性がかなりあります。 また、問題からすると、pow_fact() のプロトタイプは不適切ですね。 よしんば、求めるべきものが、(n! / (n ^ n) ではなくて) n! /(x ^ n) だったとしても、 powfact=(float)fact(d)/(float)powint(d,e); という式は、n!/(x ^ n) を正しく反映していません。 また、powint と fact という、「ほとんど同じ」にかけるはずの2つの関数が、これほどまでに違うのも、「どこかから寄せ集めた」という印象を与えるのに充分です。 plus() の冒頭にある、int x = 1; も、「何もわかっていない」と表明しているようなものです。 powint() の、int pow = 1; はそれなりに意味がありますが。 だとしたら、fact() で、同じことがされていないのは、やはり、fact() と powint() の出所が違うからでしょう。 最後に、 scanf("%d %d\n",&c, &d); は、 scanf("%d %d\",&c, &d); が正解でしょう。

Berabow
質問者

お礼

何度も回答してくださってありがとうございます<(_ _)> お返事が遅れて申し訳ありませんでした。 質問文には記入し忘れていましたけど、 「powint fact pow_fact」の三つを 使いなさいと書いてありましたので使いました。 最後のご指摘実行してみたんですが、 エラーが出てきました。 他の所に原因があるみたいです。

すると、全ての回答が全文表示されます。
  • rentahero
  • ベストアンサー率53% (182/342)
回答No.6

#3(2問目)の補足について >補足1について…powintを使うようです。 質問の問題文にはpowint・fact・pow_factのすべてが必要なように書いてあるように読めますが違いますか。 プロトタイプ宣言とは、 例えば fopen(3)だと FILE *fopen(const char *path, const char *mode); というようなものです。 上記fopen(3)の場合、、文字列pathと文字列modeを渡してFILE*型のポインタが帰ってくる、と読めます。 ということで、プロトタイプ宣言とmain関数を補足してください。

Berabow
質問者

補足

皆さんのアドバイスを読みながらやってみたら 二問目はこんな感じで上手くいきました。 (さっきからコピペが上手くいかないんでどっか かけてるかもしれませんが…(;´∀`)) ******************** #include <stdio.h> int powint(int, int); int fact(int); float pow_fact(int, int); int main(void){ int i, n; printf("Input number\n"); scanf("%d",&n); for(i=1; i<=n; i++){ printf("%10d %20.9f\n",i,pow_fact(i,i)); } } int powint(int a,int b){ int pow=1,i=b; while(i-->0){ pow*=a; } return pow; } int fact(int c){ int j, fact; fact=1; for(j=1; j<=c; j++){ fact*=j; } return fact; } float pow_fact(int d,int e){ float powfact=0; powfact=(float)fact(d)/(float)powint(d,e); return powfact; } ************************* 二問目が上手くいったんでほっとしてたんですけど …一問目が上手くいきません。 どう上手くいかないかというと、 このプログラムはキーボードで打ち込んだ 二つの数字を読み込んでそれを足すプログラムなはずなんですが、 「5 5」と打ってエンターを押しても改行されるだけで 全く計算してくれません(;´Д`)なんですけど、 「5 5 5」と三個以上の数字を入力すると 「5+5=10」とちゃんと計算してくれます。 いったいどこがおかしいんでしょうか(;・∀・) #include <stdio.h> int plus(int a, int b) { int x = 1; x=a+b; return x; } int plus(int a,int b); int main(void) { int c,d; printf("Input two integer numbers\n"); scanf("%d %d\n",&c, &d); printf("%d+%d=%d\n",c, d, plus(c,d)); return 0; }

すると、全ての回答が全文表示されます。
回答No.5

No.1 です。 実行例から逆算すると、2番目の問題で求めるのは、 n!/(n^n) ですね。x は関係なく。

すると、全ての回答が全文表示されます。
  • rentahero
  • ベストアンサー率53% (182/342)
回答No.4

#2について ごめんなさい、ちゃんと見てなかったのはこちらでした。 plusのプロトタイプ宣言は必要ありません。 int plus(int a, int b)ってちゃんと書いてありますね。 ということで、main関数の方だけで結構です。

Berabow
質問者

補足

すみません、まだ出来てないので もう少し時間をもらってよろしいでしょうか? 出来る限り問題も自分で進めてみたいです。

すると、全ての回答が全文表示されます。
  • rentahero
  • ベストアンサー率53% (182/342)
回答No.3

2問目 関数にどういう型の引数がいくつあるのか、戻り値の型は何なのかがまったくわかりません。 補足要求その1 ・fact ・powint ・pow_fact の各関数のプロトタイプ宣言を補足してください。 補足要求その2 「n!/xのn乗」が以下のどちらかを補足してください。 n!/(x^n) (n!/x)^n 補足要求その3 「実行例を入力・表示可能なmain関数」をちゃんと作って、それを補足してください。右の実数値は各行すべて定数の1を実数型の変数に代入して表示してください(すべて1.000000000になっている状態で結構です)。 ただし、コンパイルエラーはちゃんとデバッグしてください。

Berabow
質問者

補足

補足1について…powintを使うようです。 補足2について…確かにどちらかわかりませんね(;゜д゜)前者の方です。 補足3について…すみません、まだそこも解けてないもので…(・ω・`;)            今からやってみます。夕方までにはもう一度補足で            書き込めるようにしておきます。 わかりにくい質問文で申し訳ありません<(_ _)> 実は自分も何をすればいいかよくわかってないもので('A`) 今後はそういうところにも出来るだけ気をつけてみます。

すると、全ての回答が全文表示されます。
  • rentahero
  • ベストアンサー率53% (182/342)
回答No.2

え~これだけでは回答できません。補足してください。 1問目について。 plus関数のプロトタイプ宣言を補足してください。 「実行例が動作可能なmain関数」をちゃんと作って、それを補足してください。ただし、最後の4+5=9のうち、4と5は、手前で入力したものがそのまま表示されていなければなりません。 2問目は次。

すると、全ての回答が全文表示されます。
回答No.1

最初の問題は int plus( int a, int b){ int y = 1; ← この時点で既に違います。 ココがわからない return y; } 次の問題は、問題自体意味不明です。 x って何? あと、会場は、「階乗」の間違いとして、 因数は、「引数」の間違い。これは、「ひきすう」と読みます。

すると、全ての回答が全文表示されます。

関連するQ&A