ページ 11

関数呼び出し

Posted: 2009年7月28日(火) 15:35
by kamiya
void func(int no)
{
     if(no > 0) {
	func(no - 1);
	printf("%d", no);
	func(no - 2);
	}
}
上のに示す関数をfunc(3)と呼び出したときの実行結果を示せ。
という問題が参考書にあり,解いてみたのですが,さっぱり分かりません。
func(3)と呼び出す → func(no - 1)の部分で func(2)を呼び出す。
func(2)と呼び出す → func(no - 1)の部分で func(1)を呼び出す...。
これがno = 0になるまで繰り返され…る…?わけないしなぁ…と思い,
実際に組んでみると"1231"となったのですが、
肝心のなぜこうなるのか,がさっぱりです。

OS: Windows Vista
コンパイラ:Visual C++ 2008 Express
どの程度C言語を理解しているか:ど素人(独学2ヶ月程度)

どなたかご教授していただければ幸いです。

Re:関数呼び出し

Posted: 2009年7月28日(火) 16:38
by ねこ
呼び出した関数の内部処理を入れ子にすると以下のようなイメージ図になります。
func(3)					// 呼び出し元
{
	func(3-1)			// 3-1>0だから実行
	printf(3)			// プリント(3)
	func(3-2)			// 3-2>0だから実行
}
↓内部処理を加えたイメージ
func(3)					// 呼び出し元
{
	func(3-1)			// 3-1>0だから実行
	{
		func(2-1)		// 2-1>0だから実行
		{
			func(1-1)	// 1-1>0じゃないから何もしない
			printf(1)	// プリント(1)
			func(1-2)	// 1-2>0じゃないから何もしない
		}
		printf(2)		// プリント(2)
		func(2-2)		// 2-2>0じゃないから何もしない
	}
	printf(3)			// プリント(3)
	func(3-2)			// 3-2>0だから実行
	{
		func(1-1)		// 1-1>0じゃないから何もしない
		printf(1)		// プリント(1)
		func(1-2)		// 1-2>0じゃないから何もしない
	}
}
それぞれfuncの引数が0以下の時に何もしなくなります。

Re:関数呼び出し

Posted: 2009年7月28日(火) 16:43
by non
>func(3)と呼び出す → func(no - 1)の部分で func(2)を呼び出す。
>func(2)と呼び出す → func(no - 1)の部分で func(1)を呼び出す...。
>これがno = 0になるまで繰り返され…る…?

この考え方であってます。
これを再帰呼び出し(リカーシブコール)といいます。

no <=0 になったら、その呼び出された関数は終わりますから、
呼び出した関数に戻り、
printf("%d", no); が行われます。

Re:関数呼び出し

Posted: 2009年7月28日(火) 22:16
by kamiya
ありがとうございました。
かなり分かりやすかったです。