• ベストアンサー

c言語の再帰について教えてください。

c言語を勉強してるんですが、再帰のイメージがなかなかつかめません。 例えば、入力した文字列を逆から一文字ずつ表示させるのには どうしたらいいのか教えてください! 入力:ABCDE E D C B A ソースで処理される順序など説明等していただけたらうれしいです。

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

  • ベストアンサー
  • salsberry
  • ベストアンサー率69% (495/711)
回答No.5

この処理をする関数をf()とします。引数は文字列を指すポインタとします。 f()の処理はこのようになります。 a. もし引数のポインタが指す文字列が長さ0ならば、何もしないでリターン b. そうでない場合(長さ1以上): 引数の指す文字列を "XYZ" とすると、 b-1. 先頭の1文字を除いた "YZ" を指すポインタを引数として、f()を呼ぶ b-2. 次に、1文字目の"X"を表示してリターン 再帰処理の流れを図示するとこのようになります。 f("ABCDE")を呼ぶ   b-1. f("BCDE")を呼ぶ     b-1. f("CDE")を呼ぶ       b-1. f("DE")を呼ぶ         b-1. f("E")を呼ぶ           b-1. f("")を呼ぶ             a. 何もしないでリターン           b-2. "E"を表示してリターン         b-2. "D"を表示してリターン       b-2. "C"を表示してリターン     b-2. "B"を表示してリターン   b-2. "A"を表示してリターン     

age_03
質問者

お礼

なるほど。非常にわかりやすいですね。 ありがとうございました!

その他の回答 (4)

  • jx-word
  • ベストアンサー率40% (38/94)
回答No.4

学校の課題かなんかですかね? No.2の方がその処理は再帰に適していないと書いてますが、 再帰の演習問題としては結構いい感じだと思います。 再帰の考え方の基本は、大きな情報まとめて処理するより、 小さな情報に分割して再度自分自身を実行すると言うことになります。 質問の内容であれば、5文字の処理は面倒なので1文字だけ処理して、残りは再帰で処理するという感じです。 コードを書かずに説明するのは難しい・・・・

age_03
質問者

補足

1文字だけ処理して、残りは再帰で処理する そういう考え方なのですね。ヒントをいただけたので 考えてみたいと思います!ありがとうございました。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.3

> C言語で書くとこうなります。 こうなる場合がある、というのが正確でありましょう。 戻り値を取る再帰関数もありますしね。

age_03
質問者

お礼

なるほど。意外と簡単に書けるんですね。 最後の入力文字からprintfされるという理屈がまだ あいまいなのでもうちょと勉強します!

  • LegaC2
  • ベストアンサー率52% (224/428)
回答No.2

質問に記載されている例は、再帰に適していないと思います。 再帰関数とは、自分自身を繰り返し、呼び出す関数を指します。 C言語で書くとこうなります。 ある条件を満たす限り、自分自身を呼び続けます。 void Recursive() { if( ある条件 ) Recursive() } 例えば、以下のような家族構成の人物がいます。 山本太郎:自分自身 山本一郎:山本太郎の長男 山本次郎:山本太郎の次男 山本花子:山本太郎の長女 山本一男:山本次郎の長男 そして、ここに以下のような再帰関数があったとします。 void 名前表示関数( 人物 ) { 本人の名前を表示 --- (A) if( 子供がいたら ) --- (B) { for( 一人ずつ ) { 名前表示関数( 人物 ) --- (C) } } } この名前表示関数に山本太郎を与えると以下のように処理が流れます。 1. 山本太郎の名前を表示(A) 2. 山本太郎には子供がいるので、(B)の条件を満たす 3. まずは、一人目の山本一郎を名前表示関数に与える(C) 3-1. 山本一郎の名前を表示(A) 3-2. 山本一郎には子供がいないので、(B)の条件は満たさない 3-3. そのまま関数を抜ける 4. 次に、二人目の山本次郎を名前表示関数に与える(C) 4-1. 山本次郎の名前を表示(A) 4-2. 山本次郎には子供がいるので、(B)の条件を満たす 4-3. 山本一男を名前表示関数に与える(C) 4-3-1. 山本一男の名前を表示(A) 4-3-2. 山本一男には子供がいないので、(B)の条件は満たさない 4-3-3. そのまま関数を抜ける 4-4. 山本次郎にはこれ以上子供がいないので、関数を抜ける 5. 次に、三人目の山本花子を名前表示関数に与える(C) 5-1. 山本花子の名前を表示(A) 5-2. 山本花子には子供がいないので、(B)の条件は満たさない 5-3. そのまま関数を抜ける 6. 山本太郎にはこれ以上子供がいないので、関数を抜ける 以上で終了となります。 結果として、以下のような順番で名前が表示されます。 山本太郎 山本一郎 山本次郎 山本一男 山本花子 簡単に説明するとこんな感じです。 要は、深さが一概に判断できないような場合にこのような関数を作成し、繰り返し処理を行います。 一度、簡単なプログラムを作成することをお勧めします。

age_03
質問者

お礼

ノートに書きながら順番を追っていくとだんだんつかめてきました。 ありがとうございました!

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

その問題をどうしても再帰呼び出しで実装したいのであれば、 例えばこんな感じでしょうか。 #include<stdio.h> int main(void) { int c; while ((c = getchar()) != EOF) { main(); printf("%c\n", c); } return 0; }

関連するQ&A

  • C言語で、再帰呼び出しを使用せずに、文字列"(12 + 3) * (

    C言語で、再帰呼び出しを使用せずに、文字列"(12 + 3) * ( 3 * (4 + 5 ))"を、優先順位が低い順に二分木に入れる関数を作成したいのですが・・・。 char str[15] = ""(12 + 3) * ( 3 * (4 + 5 ))";なら char n[100];に n[0] = '*' n[1] = '+' n[2] = '*' n[3] = 12 n[4] = 3 n[5] = 3 n[6] = '+' n[7] = \0 n[8] = \0 n[9] = \0 n[10] = \0 n[11] = \0 n[12] = \0 n[13] = 4 n[14] = 5 (n[15] 以降は\0が格納されています。) というように入れたいのですが関数からその関数を呼び出す再帰を使わずに作成する方法がわかりません。 再帰を使用しなければかなり処理が複雑になるような気がしますがどなたか詳しい方よろしくお願いします。 言語はC言語です。

  • C言語

    今、独学でC言語を勉強しているんですが。 大きく、 条件処理、繰り返し処理、配列、関数、2次元配列、文字列、構造体、ファイル処理、乱数、検索、バブル・ソート、ポインタ まではやったんですが(参考書で勉強)。 その次になにを勉強したらよく分からないので、 何を勉強するべきか教えてください。 将来的にこれっと言った作りたいものは決めていません。 お願いします。

  • C言語 再帰処理のメリットとデメリット

    最近、C言語の関数にも再帰定義ができるということを初めて知りました。 そこで聞きたいのですが、再帰処理のメリット・デメリットは何でしょうか? 思いついたものとしては メリット … 簡単に表記できる デメリット … 無限ループが発生する可能性あり でしょうか。 また、全計算が終わるまでに、途中の演算結果を保持しなければならないので、 メモリを無駄遣いしそうな気もします。

  • C言語での文字列より値を抜き出す

    C言語初心者です。 たとえば、”ABCDE”という文字列があります。 その文字列の2桁目から3文字を取得したい場合、 どのようにすればよろしいでしょうか。  上記の場合、”BCD”が欲しい SQLだと、SUBSTR(B)関数がありますが、C言語には 同様な関数があるのでしょうか。 また、C++ではどうでしょうか。 お客さんに突然聞かれたので、本屋に行く余裕もありませんでした。 どなかた教えてください。お願いします。

  • C言語のプログラミングですが、

    C言語のプログラミングですが、 255文字以内の文字列をキーボードから入力して、下記の各処理を行うプログラム(※入力した文字データは配列に入力)はどのようにしたらいいでしょうか?(入力例:acFNkeexFFg) ・入力した文字列の最後の文字を出力 ・入力した文字列⇒逆に並べ替えて出力 ・入力した文字列⇒縦に出力(1文字ずつ) ・入力した文字列の中に「F」が何個あるか ただし、使えるのはfor文・配列・if文ぐらいでそれ以上レベルの高いものは使わないで下さい。 … char str[255]; int i,n,na,nb,nc; printf("Input Strings= "); scanf("%s",str); for(i=0;str[i]!='¥0';i++){ n=i; } printf("The last character= %c",str[n]); くらいまでしか分かりません…

  • c言語について教えてほしい

    教えてください。 現在c言語を自習していますが、偶然にこういう問題を見ましたが、なかなか解けなくて、助けがほしいです。お願いします。 問題: fopen,fputs,fcloseを使って、次のプログラムを作成しなさい。文字列とファイル名を入力させ、ファイルを生成する。(入力したファイル名に拡張子.txtを付与する。) 表示イメージ: 文字列を入力して下さい。 ファイル書き込みテストをします。注意します (←入力する) ファイル名を入力して下さい。 testei (←入力する) ファイルの書き込みに成功しました。 ファイルイメージ: testi.txt (←入力したファイル名 拡張子.txtが付与される) ファイル書き込みテストをします。注意します (←入力した文字列)

  • 再帰について(C言語)

    今、再帰処理を勉強しています。 しかし、以下のプログラムがどうしても理解できません。 流れ的には一体どういう手順になっているのでしょうか? return i * fact( i - 1 )の部分を考えると頭が こんがらがってしまいます。 #include <stdio.h> int main( void ){  printf("5の階乗は %d です", fact(5) );  return 0; } int fact( int i ){  if( i == 1 ) return 1;  else return i * fact( i - 1 ); } --------実行結果---------- 5の階乗は 120 です

  • C言語の問題で困っています。

    C言語の問題で困っています。 途中までできたのですが、この先が分かりません。 教えて頂くようお願いいたします。 【問題】 文字列の長さを求めるプログラムです。このプログラムを、入力した文字列の文字列長を求めるように変更してみましょう。  ただし、入力する文字列は半角で最大 20 文字までとし、指定された範囲外の値( 21 以上)が入力された場合は、正しい値が入力されるまで入力処理を繰り返すこと。 #include <stdio.h> int main(void) { char str[256] = "Hello"; int length, i; printf("文字列:"); scanf ("%s",str); length=0; i=0; while (str[i]!='\0') { i++; length++; } printf("\n文字列長:%d\n",length); }

  • C言語

    課題なんですが、C言語で 「文字列と正数nをキーボードから入力して、1行n文字で改行するプログラム」 をつくりたいのですが、わかりません。どうすればよいのですか?

  • C言語でゲーム

    今、独学でC言語を勉強しているんですが。 大きく、 条件処理、繰り返し処理、配列、関数、2次元配列、文字列、構造体、ファイル処理、乱数、検索、バブル・ソート、ポインタ を勉強したんですが。 もしも、ゲームを作るとしたら・・ もし、ボンバーマンみたいなのを作るとなるとどういう勉強をすればいいんでしょうか? もうひとつはHALOみたいなxbox関係などはどの様な勉強をすればいいんでしょうか? 質問が多いですが、よろしくお願いします。