- ベストアンサー
c言語の関数定義について
次の関数定義を考える. int f(int x) {if (x > 0) {return x * f(x-1);} else {return 1;} } この関数f と働き(すなわち,引数と戻り値の関係)が同じで再帰呼出(recursive call) を使わない関数g をC で定義せよ.ただし,オーバーフロー(overflow) については考慮しなくてよい. ”この関数f と働き(すなわち,引数と戻り値の関係)が同じで再帰呼出(recursive call) を使わない関数g をC で定義せよ”って理解できません、どのように定義したいいか、ご教授お願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
とゆ訳で、題意に沿った解答は int g(int x) { int ans; int i; ans = 1; for (i = 2;i <= x;i++) { ans *= i; } return ans; } ここで、xが2未満(1と0以下、つまり1以下)の時は、forループを回らない事に注意しましょう。 ループを回らない場合、1で初期化したansがそのまま「関数の戻り値」になりますので、1以下の引数を与えられた場合は常に1を返します。 また、元のf()関数は「0より大きい、つまり、1以上ならばx * f(x-1)を、1未満なら1を返す」としていますが、上記のプログラムは「1より大きい、つまり2以上ならばループを回る」となっていて、判断数値が微妙に違います。 これは f(引数xが2以上)→1~xまでの掛け算の答えを返す f(引数xが1)→1 * f(0)、すなわち、1 * 1、結局は1を返す f(引数xが0以下)→1を返す となっていて「f(1)は1を返すんだから、f(0以下)と同じ処理をしても構わない」というのが理由です。 つまり「0以下なら1を返す」のと「1以下なら1を返す」のは、結果が同じになるって言うのが理由です。 試しに、元の関数f()をちょっと改造してf2()関数を作って int f2(int x) {if (x > 1) {return x * f2(x-1);} else {return 1;} } としても、判断数値が違うにも関わらず、関数f()とまったく同じ働きをします。 蛇足ですが、私なら int f3(int x) {return (x > 1) ? x * f3(x-1) : 1;} と書きます。
その他の回答 (4)
- asuncion
- ベストアンサー率33% (2127/6290)
テスト用main関数付き #include <stdio.h> int f(int x) { if (x > 0) { return x * f(x-1); } else { return 1; } } int g(int x) { int ans = 1; while (x > 0) { ans *= x--; } return ans; } int main(void) { int valid, i; for (valid = 1, i = -1; i <= 10; i++) { int a = f(i), b = g(i); printf("%2d:%10d%10d\n", i, a, b); if (a != b) { valid = 0; } } printf("\nf()とg()は等価と見なせま%s。\n", valid ? "す" : "せん"); return 0; }
お礼
詳しく教えていただいて、どうもありがとうございます。
- chie65536(@chie65535)
- ベストアンサー率44% (8800/19959)
>”この関数f と働き(すなわち,引数と戻り値の関係)が同じで再帰呼出(recursive call) を使わない関数g をC で定義せよ”って理解できません >どのように定義したいいか、ご教授お願いします。 Cでは「関数を定義する」とは「関数を作る」って意味です。 要は「再帰を使わないで、同じ仕様の関数を作れ」って事。 >このようにして、ただしいですか? >int g(int x) >{ >int sum=x; >while(--x) >sum*=x; >return sum; >} 残念ながら、私が教授なら評価は「不可」です。 「f(0)」や「f(-1)」は、1を返しますが、質問者さんの関数はそうなっていません。 「同じ働きをしていない。引数に0や負数を入れると結果が異なる。題意に沿った解答ではないので、評価は不可」です。
お礼
詳しく教えていただいて、どうもありがとうございます
- asuncion
- ベストアンサー率33% (2127/6290)
関数fとgに同じ引数を与えたときに同じ結果を得れば、 題意に沿った関数gを定義できたと見なせるでしょう。 何かの「合計ではない」のにsumという名前を付けるのはどうなんだろう?というのはありますけれど…。
お礼
asuncionさん、了解しました。どうもありがとうございます。
- NNori
- ベストアンサー率22% (377/1669)
たとえば、f(10) は何を返すかわかりますか? 10は 0より大きいので、 10 * f(9) を返しますよね? f(9) は 9 * f(8) です。 f(8) は 8 * f(7) です。 ... f(0) は x>0 を満たさないので 1 を返します。 つまり、 f(10) = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 * 1 となります。 こんな答えを返すようにプログラムしなさい!っていう意味です。
お礼
NNoriさん、詳しく教えていただいて、どうもありがとうございます。このようにして、ただしいですか? int g(int x) { int sum=x; while(--x) sum*=x; return sum; }
お礼
詳しく教えていただいて、どうもありがとうございます。