• ベストアンサー

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 で定義せよ”って理解できません、どのように定義したいいか、ご教授お願いします。

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

  • ベストアンサー
回答No.4

とゆ訳で、題意に沿った解答は 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;} と書きます。

takahasi77
質問者

お礼

詳しく教えていただいて、どうもありがとうございます。

その他の回答 (4)

  • asuncion
  • ベストアンサー率33% (2127/6290)
回答No.5

テスト用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; }

takahasi77
質問者

お礼

詳しく教えていただいて、どうもありがとうございます。

回答No.3

>”この関数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や負数を入れると結果が異なる。題意に沿った解答ではないので、評価は不可」です。

takahasi77
質問者

お礼

詳しく教えていただいて、どうもありがとうございます

  • asuncion
  • ベストアンサー率33% (2127/6290)
回答No.2

関数fとgに同じ引数を与えたときに同じ結果を得れば、 題意に沿った関数gを定義できたと見なせるでしょう。 何かの「合計ではない」のにsumという名前を付けるのはどうなんだろう?というのはありますけれど…。

takahasi77
質問者

お礼

asuncionさん、了解しました。どうもありがとうございます。

  • NNori
  • ベストアンサー率22% (377/1669)
回答No.1

たとえば、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 となります。 こんな答えを返すようにプログラムしなさい!っていう意味です。

takahasi77
質問者

お礼

NNoriさん、詳しく教えていただいて、どうもありがとうございます。このようにして、ただしいですか? int g(int x) { int sum=x; while(--x) sum*=x; return sum; }

関連するQ&A