※2020/03/09 コメントを受けて追記
再帰についての理解を体に染み込ませるためにいろいろ再帰を使ったコードを考えてみる。
配列の合計値を出すコード
# include <stdio.h>
int arraySum(int *a, int b, int i)
{
if(b > 0){
--b;
i +=a[b];
return arraySum(a, b, i);;
} else {
return i;
}
}
int main(void)
{
int a[6] = {1,3,4,5,7,8};
int b = 6;
int i = 0;
printf("%d\n", arraySum(a,b,i));
return 0;
}
気づいたこと
- int型の配列と再帰の組み合わせは、アドレス__の他に__配列数、__シード値__が必要。
- 渡すものが多いので野暮ったい印象。
文字列を出力するコード
# include <stdio.h>
void printstr(char* str)
{
if(*str != '\0'){
printf("%c", *str);
str++;
printstr(str);
}
}
int main(void)
{
char str[] = "Aiueo";
printstr(str);
printf("%c", '\n');
return 0;
}
気づいたこと
- 文字列は終点のデータが存在するという部分において__リスト構造__と同じデータ構造。だから、再帰的な処理を書くときに文字列は__int型の配列__に比べて__シンプルに定義__できる。
- __帰納的定義__と__再帰__の関係への理解が深まった。
追記
以下のような書き方もあるとコメント頂いた。
int arraySum(int *a, int n)
{
if(n <= 0) return 0;
return *a + arraySum(a + 1, n - 1);
}
配列をインクリメントできる仕様を使ったスマートな書き方。
与えられた配列数をカウントのみに使用して、再帰的に書いている。
自分の書いたコードは見た目に違和感があったのだが、このコードでは解決されている。