我有一本C书的递归函数如下:
void print(int a[], int n)
{ if (n<=0) return ;
printf("%d\n", a[0]);
print(&a[1], n-1);
}
我已经运行并且此函数打印指定数组的所有元素。但我真的不明白这个功能是如何工作的,所以我可以打印数组的所有元素。 请问有人能给我一个明确的解释吗?
答案 0 :(得分:5)
&a[1]
是数组的第二个元素的地址,它实际上是第一个元素之后的数组部分的地址。因此,在打印参数数组的第一个元素后,
print(&a[1], n-1);
将数组的剩余部分传递给自己,同时将长度减少一个。
例如,如果您使用数组print
和{1, 2, 3, 4, 5}
致电n == 5
,则事件和调用链如下:
{2, 3, 4, 5}
和n == 4
{3, 4, 5}
和n == 3
{4, 5}
和n == 2
{5}
和n == 1
{}
和n == 0
n<=0
- &gt;返回答案 1 :(得分:2)
此函数将数组的剩余部分作为参数以及它包含的元素数量。每次打印第一个元素,然后递归调用剩余部分。这是一个例子:
array: 1, 2, 3, 4, 5, 6; N = 6
array: 2, 3, 4, 5, 6; N = 5
array: 3, 4, 5, 6; N = 4
array: 4, 5, 6; N = 3
array: 5, 6; N = 2
array: 6; N = 1
array: ; N = 0 return;
答案 2 :(得分:1)
数组基本上是指向第一个元素开头的指针,所以你的代码基本上是这样的:
void print(int *a, int n)
{ if (n<=0) return ;
printf("%d\n", *a);
print(a+1, n-1);
}
递归调用是传入指向数组中下一项的指针并减少计数,这是您在递归终止条件中使用的。
答案 3 :(得分:1)
所以它做了以下事情:
答案 4 :(得分:1)
了解递归的好方法IMHO是在调试器中运行代码,并观察调用堆栈和变量。
答案 5 :(得分:1)
如何打印零大小的数组? 容易:你没有
这是你的if (n<=0) return;
如何使用1个元素打印数组? 简单:只需打印元素 并将其从数组中删除并按原样打印生成的零大小数组
这是你的printf("%d\n", a[0]);
如何使用2个元素打印数组? 简单:打印第一个元素并将其从阵列中移除并按原样打印生成的一个大小的数组
这是你的print(&a[1], n-1);
答案 6 :(得分:0)
如果n
为零(或更小),则不执行任何操作,因此递归停止。如果n
&gt; 0,然后打印a[0]
并以n-1
为n
递归调用自身(因此递归进行时为0),&a[1]
为a
,即它在每次递归调用中递增指针a
。请记住,C中的数组参数是指针参数的语法糖。
因此,您发布的代码相当于:
void print(int *a, int n)
{
if (n > 0) {
printf("%d\n", *a);
print(a+1, n-1);
}
}
答案 7 :(得分:0)
如果您可以验证以下算法是否适用于打印数组,您应该能够理解C代码的工作原理,因为它是直接翻译。
打印数组的n个元素:
答案 8 :(得分:0)
每次打印调用都会这样做:
你究竟不懂什么?
答案 9 :(得分:0)
它相当于一个循环:
int i ;
for (i = 0 ; i< n ; i++) {
printf("%d\n",a[i]);
}
为什么呢?好吧,递归总是查看第一个元素并打印它,然后通过查看第二个元素中的数组(现在是下一个迭代中的'first'),它们前进到下一个元素。 你的停止条件是当没有剩余元素时 - 即一个长度为0的数组。
答案 10 :(得分:0)
该函数接受一个数组和数组的长度。
if(n<=0) return;
如果数组的长度为&lt; = 0,则函数返回。
printf("%d\n", a[0]);
数组的第一个元素,即元素0。
print(&a[1], n-1);
&amp; a [1]获取指向数组第一个元素的指针。数组和指针可以互换使用,因此当函数传递给函数时,函数可以将它视为一个新数组,从前一个数组的第二个元素开始,长度减少一个。