• 締切済み

再帰

iが10以下の時、a ( i+1 ) ;の部分が実行され printf文は飛び越されますよね? iが10になると、if文は実行されませんよね。 実行結果は9876543210となるのですが、解りません。 どう読み込まれるのか解説お願いします。 a ( 0 ) の時、 void a(int i) {   if ( i<10 ){   a ( i+1 );   printf ( "%d",i );   } }

みんなの回答

  • Trick--o--
  • ベストアンサー率20% (413/2034)
回答No.4

実行される順に a(i){  a(i+1){   ...   printf(i+1)  }  printf(i) } という風に書くと a(0){  a(1){   a(2){    a(3){     a(4){      a(5){       a(6){        a(7){         a(8){          a(9){           a(10){            (ifの条件が偽なのでなにもしない)           }           printf(9)          }          printf(8)         }         printf(7)        }        printf(6)       }       printf(5)      }      printf(4)     }     printf(3)    }    printf(2)   }   printf(1)  }  printf(0) } これが上から順に実行されるので、最終的な表示が 9876543210 となります

startover
質問者

お礼

回答どうもありがとうございます。 if条件が偽、 printfで9876543210と戻ってくる所がわかるような、あやふやな感じなんですが、じっくり考えて見ます! ありがとうございました。

  • herbest
  • ベストアンサー率42% (15/35)
回答No.3

もっとループ回数を減らして「if ( i < 1 )」ぐらいで 考えてみてはどうですか? もしくは次のように別関数として考えてみるとか。 void a(int i) {   if ( i < 2 ){   b ( i + 1 );   printf ( "%d",i );   } } void b(int i) {   if ( i < 2 ){   c ( i + 1 );   printf ( "%d",i );   } } void c(int i) {   if ( i < 2 ){   printf ( "%d",i );   } } イメージわきました?

startover
質問者

お礼

すばやい回答ありがとうございます。 ループの数を減らしてみると、なんとなくイメージがつかめました。 ループ数が増えると、解らなくなりますが。 再帰のなんとなくのイメージは解りました! ありがとうございます。

  • crew21
  • ベストアンサー率26% (58/222)
回答No.2

No.1さんの仰る通りです。説明上手いなあ。。 再帰ってけっこうイメージしにくくて初心者にはひっかかるところなので、もしNo.1さんの説明で分からないようでしたら、随所にprintf分を入れて実行してみるといいですよ。 例えばa関数に入ってすぐの箇所でprintf("関数に入った iは%d\n", i);とか、関数から抜ける箇所でprintf("関数から抜ける iは%d\n", i);とかやるとプログラムの動きが見えやすくなります。 再帰は一つ間違うとメモリ(スタック)を食いつぶしたりするので、気を付けてくださいね。

startover
質問者

お礼

すばやい回答ありがとうございます。 随所にprintf分を入れて実行してみるといいですよ。 これはいいアイデアですね。 いろいろ試してみます。 ありがとうございました。

  • rinkun
  • ベストアンサー率44% (706/1571)
回答No.1

iが10未満のときprintfは飛び越されるのではなく a(i+1)を実行して帰ってきてから実行されます。 だから a(0), a(1), ..., a(9)ときてa(10)ではa(11)とprintfは実行されず 後は戻りながらa(9)のprintf、a(8)のprintf、と実行されます。 結果として9876543210と表示されることになるわけです。

startover
質問者

お礼

すばやい回答ありがとうございます。 よく理解を深めるため参考にさせていただきます。 ありがとうござうました。

関連するQ&A

  • 再帰について(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 です

  • 再帰呼び出し

    アッカーマン関数の値を出力するプログラム #include void main(void); int ack(int,int); void main(void) { int x,y,i; printf(" data(x) = "); scanf("%d",&x); printf(" data(y) = "); scanf("%d",&y); i = ack(x,y); printf("Ackerman = %d\n",i); } int ack(int a,int b) { int k; if (a == 0) k = b+1; else if (b == 0) k = ack(a-1,1); else k = ack(a-1,ack(a,b-1)); return (k); } この関数を呼び出した回数も出力するようにしたいのですが、どうしたらいいのでしょうか?

  • 再帰について

    こんばんは。 今、大学でC言語の勉強しているのですが、昨日再帰についての講義がありました。 講義の中で以下のプログラムを作成したのですが、このプログラムの 実行結果がなぜ以下のようになるか分かりません。 どなたかご教授ください。 結果:9 8 7 6 5 4 3 2 1 0 プログラム: #include<stdio.h> main() { function(0); } function(int i){ if(i<10) { function(i+1); printf("%2d",i); return i; } }

  • for文~break

    break文に達した時、for文から抜けますか?それとも、if { }から抜けるんですか? for文はどこまで影響下にありますか? if ( i==5 ) printf ("サーバーが見つかりません"); まででしょうか? また  if ( i == 5 ) で5なら、実行としていますが、 6,や,8など5 以外でも、サーバーが見つかりません と if文が実行される見たいですが、なぜですか? 教えてください。 #include<stdio.h> int main(void) { int array[5][2]={ {1,14}, {2,28}, {3,19}, {4,8}, {5,15}, }; int sever; int i; printf("番号を入力してください"); scanf("%d",&sever); for( i=0 ; i<5 ; i++ ) if ( sever == array[i][0] ){ printf ( "%d 番には, %d 人います。\n",sever,array[i][1]); break; } if (i==5) printf("サーバーが見つかりません"); return 0; }

  • 素数 再帰関数

    メイン #include<stdio.h> extern void count_primes(void); extern void print_primes(void); int max; int count; int primes[1000] int main(void) { printf("Uper limit: "); scanf("%d",&max); count_primes(); print_primes(); } 素数を求める(関数呼び出し) extern int nextprime(int n); extern int max; extern int count; extern int primes[]; void count_primes(void) { int i; count=0; for(i=2;i<=max;i=nextprime(i)){ primes[count++]=i; } リカーバシブ(次の素数) int nextprime[int n] { int i; for(;;){ n++; for(i=2;i*i<=n;i=nextprime(i)){ if(n%i==0) break; } if(i*i>n) break; } return n; } 素数プリント #include<stdio.h> extern int count; extern int primes[]; void print_primes(void) { int i for(i=0;i<count;i++){ if((i>0)&&(i%10==0) printf("\n"); printf(" %6d",primes[i]); } printf("\n素数の数 %d\n",count); } これら4つのモジュールで素数 nが求められますがアルゴリズム理解できません。この2つの関数のアルゴリズムについて、ご教授ください。め

  • 配列について(C言語)

    配列の要素において一番目の要素以外を0にするプログラムを以下のように作成したのですが(while文を*b != 0という条件で作りたい)、while文内のところが間違っているためだと思われるのですが、うまく実行されません(実行しても何も表示されない)。どのようにしたらいいのでしょうか。または、何かが抜けている、ほかの部分が間違っている等もあるためにうまく実行されないということなのでしょうか。 #include <stdio.h> int main(void) { int a[5] = {5, 78, 2, 9, 0}; int i, *b; b = &a[0]; while (*b != 0){ if(*!=a[0]) *ptr=0; else *ptr=a[0]; } for (i = 0; i < 5; i++){ printf("ptr値 =%d ptrアドレス =%p \n", *ptr, ptr); } printf("\n"); return (0); }

  • C言語で再帰的処理が出来ない理由

    以下のサイトでC言語の勉強をしているのですが、このサイトのソースコードをコピペして実行してみたら上手くいきませんでした。 http://wisdom.sakura.ne.jp/programming/c/c30.html ========================== #include<stdio.h> void func(int ); int main() { func(0); printf("プログラムを終了します"); return 0; } void func(int max) { if (max <= 10000) { printf("%d\r",max); func(max + 1); } } ========================== 実行してみると、何故か4700~4800の辺りで止まってエラーになってしまいます。 どうしてエラーになるのでしょうか?

  • 再帰処理 変換

    初歩的で申し訳ないのですが、10進数を2進数に変換して表示する関数dt(n)を再帰的に定義するプログラムを作ってみたのですがつまってしまいました。以下、考えたコード文です。 #include <stdio.h> /*****dt*******/ long dt(int n) {      if(n == 1)          printf("1");      else          dt(n % 2);          printf("%d" , n); } /****** Main ******/ void main(void) {      dt(10); } どこが間違えているかご指摘頂けたら有難いです。

  • 再帰の問題です。

    AOJの問題で、C言語で書いています。 ある解答者様のコードが自分の理解に深まると思い、見ているのですが、解答者様の作った関数のところの動作がよくわかりません。 問題です。 http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0030&lang=jp 解答例です。分かるところ、分からないところを書いていきます。 #include<stdio.h> int n,s,a;//グローバル変数。 void dfs(int i,int sum,int m){//ここでいう、i,sum,mが何を指しているのか分かりません。 if(m==0 && sum==s){a++;return;} if(i==10 || m==0)return; dfs(i+1,sum+i,m-1);/*再帰をしています。しかし、どうしてここに自分と同じ関数を2つ、入れている   のか、分かりません。あと、どうしてiを足したり、1引いた数を代入しているのでしょうか?*/ */ dfs(i+1,sum,m);   } int main(){ while(scanf("%d%d",&n,&s)!=EOF){//Ctrl+zを押さない限り、無限ループします。 if(n==0 && s==0)break;//問題文通り、2つとも0だったらループを表すwhileから抜けます。 a=0; dfs(0,0,n);//ここもわからないです。ただ、関数dfsの動きが分かれば、分かると思います。 printf("%d\n",a); } return 0; } 再帰は今苦戦していますので、ここでもっと理解を深め、自作関数で使えるようになりたいです。 長文失礼しました。 よろしくお願いします。

  • 関数について

    C言語の勉強をしているのですが、関数のところがよく理解できません。 ------------------------------ #include <stdio.h> int beki(int a, int b); int main(void) { int n; n=beki(2,3); printf("%d\n",n); printf("%d\n",beki(3,4)); } int beki(int a, int b) { int i,ans; ans=1; for(i=1; i<=b; i++) { ans=ans*a; } return ans; } ---------------------------- 実行結果 8 81 ----------------------------- 上のサンプルで int i,ans; ans=1; for(i=1; i<=b; i++) { ans=ans*a; } の部分は、解説書には「渡されたデータa,bを使って戻り値ansを計算 している」「aのb乗を計算している」などとありましたが、なぜaのb乗を計算しているのでしょうか?実行結果が8と81の何に関係しているのでしょう? ansやa,bの値を求めたら、何の値になるのでしょうか? これらについて、解説をお願いいたします。

専門家に質問してみよう