- 締切済み
組み合わせ プログラミング
c言語についてです os linux コンパイラはgccです long fact2(int n,int m)を作成してfact2(n,m)を使って組み合わせを計算するプログラムを作れという問題で下記のように作りましたが コンパイルできません. エラーメッセージは 2-1.c:14: error: 関数 `fact2' への引数が少なすぎます 2-1.c:14: error: 関数 `fact2' への引数が少なすぎます 2-1.c:14: error: 関数 `fact2' への引数が少なすぎます です 関数のとこが違うと思うですが どうしたらいいのかわかりません それともなにか他のとこが違うのでしょうか? #include <stdio.h> long fact2(int,int); main() { int n, m; long c; printf(" nCm (n>m) \n"); printf("input n m ="); scanf("%d %d",&n, &m); c =fact2(n) / (fact2(m) * fact2(n-m)); printf("%dC%d = %ld\n",n,m,c); } long fact2(int n,int m) { int i; long c=1; for(i=1; i<=n; i++) c*=i; return(c); }
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- Tacosan
- ベストアンサー率23% (3656/15482)
#1 の言うように, c =fact2(n) / (fact2(m) * fact2(n-m)); を c =fact2(n, 0) / (fact2(m, 0) * fact2(n-m, 0)); とでもすれば動きます. 「与えられた引数をすべて使わなければならない」という規則はないし. ま, はっきりいってこれは問題がよくないと思う. 「long fact2(int n,int m)を作成してfact2(n,m)を使って組み合わせを計算するプログラムを作れ」という問題からは「fact2 の仕様」が分からないんだよね.
- chie65536
- ベストアンサー率41% (2512/6032)
>fact2の中身でもn,m2つ使おうとしたらどうやればいいのかわからなくなってしまって・・・ 課題では long fact2(int n,int m)を作成してfact2(n,m)を使って組み合わせを計算するプログラムを作れ と指示されています。 なので long fact2(int,int); と定義しなければなりません。 main関数からは c =fact2(n,m); という形で呼び出さなければいけません。 fact2関数は long fact2(int n,int m) { return (nとmの2つの変数から、組み合わせ数「nCm」を計算する式); } と言う書き方をしないとなりません。 nとmの2つの変数からnCm計算する式は n! / (n-m)! / m! になります(ここは「n! / (m! * (n-m)!)」でも構わないが、本来の組み合わせ数の式は「(n! / (n-m)!) / m!」であるので、こちらの方が適切) Cコンパイラには階乗を演算する演算子はありませんから、階乗を返す関数が必要です。 階乗を返す関数は、質問者さんがもう作ってますから、そのまま流用します。 long fact(int x) { int i; long c=1; for(i=1; i<=x; i++) c*=i; return(c); } すると式 n! / (n-m)! / m! は fact(n) / fact(n-m) / fact(m) になります。 fact2関数の return (nとmの2つの変数から、組み合わせ数「nCm」を計算する式); の所に、この式を書けば良い事になります。 --------------- 結論は 質問者さんは「順列組み合わせ関数であるfact2(n,m)を作れ」と言う課題で、一生懸命「階乗を返す関数」を作って、順列組み合わせの式をfact2関数に書かず、main関数の中に書いてた、と言う勘違いをしていた。 って事。
- okg00
- ベストアンサー率39% (1322/3338)
はい。勘違いです。 関数と引数の関係について復習する事をお勧めします。 http://www.kumei.ne.jp/c_lang/intro/no_03.htm 関数を呼び出す際にパラメータとして扱われるのが引数です。ここで、扱うパラメータを指定します。プログラム中で何種類のパラメータで引き渡すかではありません。 fact2(n) / (fact2(m) * fact2(n-m)); では個別にfact2(n)とfact2(m)とfact2(n-m)が計算されます。fact2(n-m)では先にn-mが計算され、その結果をfact2関数のパラメータとして呼び出します。 なお、先のn,mと long fact2(int n,int m) { int i; のn,mは別物です。仮引数と実引数の差です。一緒にしないでください。 http://www.cc.kyoto-su.ac.jp/~yamada/ap/parameter_argument.html >fact2の中身でもn,m2つ使おうとしたら 無理に2つを使う必要はありません。一度に一つしか使わないなら、一つだけで構いません。
- asuncion
- ベストアンサー率33% (2127/6290)
>c =fact2(n) / (fact2(m) * fact2(n-m));に引数が2こ入っていますがこれは私の勘違いでしょうか? はい。勘違いなさっています。 fact2(n):引数は1個(n) fact2(m):引数は1個(m) fact2(n-m):引数は1個(n-m) ところで、そもそもfact2は何をする関数でしょうか。 コードを見る限り、2個目の引数mを全く使っていませんね。 もし、fact2が階乗を求める関数であれば、引数は1個あればじゅうぶんなように思います。 2個目の引数が必要な理由は、私にはちょっとわかりません。
- okg00
- ベストアンサー率39% (1322/3338)
エラーメッセージの通りですね。 プロトタイプ宣言では >long fact2(int,int); とあり、引数を2つ指定していますが、 実際に使う場面では >c =fact2(n) / (fact2(m) * fact2(n-m)); 引数を1つしか渡していません。 引数の個数を合わせてください。 ※fact2の中身ではmを使っていないようですが...
補足
c =fact2(n) / (fact2(m) * fact2(n-m));に引数が2こ入っていますがこれは私の勘違いでしょうか? fact2の中身でもn,m2つ使おうとしたらどうやればいいのかわからなくなってしまって・・・