关于递归函数的问题?
我有一个来自 C 书的递归函数,如下所示:
void print(int a[], int n)
{ if (n<=0) return ;
printf("%d\n", a[0]);
print(&a[1], n-1);
}
我已经运行并且该函数打印指定数组的所有元素。但我真的不明白这个函数是如何工作的,以便我可以打印数组的所有元素。 谁能给我一个明确的解释吗?
I have a recursive function from a C book as follows:
void print(int a[], int n)
{ if (n<=0) return ;
printf("%d\n", a[0]);
print(&a[1], n-1);
}
I have run and this function prints all the element of the specified array. But I really do not understand how this function works so that I can print all elements of an array.
Can anyone give me a clear explanation, please?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
&a[1]
是数组第二个元素的地址,它实际上是数组中第一个元素之后的部分的地址。因此,在打印参数数组的第一个元素后,将数组的剩余部分传递给自己,同时将长度减一。
例如,如果您使用数组
{1, 2, 3, 4, 5}
和n == 5
调用print
,则链事件和调用如下:{2, 3, 4, 5}
和n == 4
{3, 4, 5}
和n == 3
{4, 5}
和n == 2
{5}
和n == 1
{}
和n == 0
n<=0
->返回&a[1]
is the address of the second element of the array, which is effectively the address of the portion of the array after the first element. So after printing the first element of the parameter array,passes itself the remaining portion of the array, decreasing the length by one as well.
For example, if you call
print
with the array{1, 2, 3, 4, 5}
andn == 5
, the chain of events and calls is the following:{2, 3, 4, 5}
andn == 4
{3, 4, 5}
andn == 3
{4, 5}
andn == 2
{5}
andn == 1
{}
andn == 0
n<=0
-> return该函数将数组的剩余部分及其包含的元素数量作为参数。每次打印第一个元素,然后递归调用其余部分。这是一个例子:
This function takes as arguments the remaining part of the array and how many elements it contains. Every time you print the first element and then call recursively of the remaining part. Here is an example:
数组基本上是指向第一个元素开头的指针,因此您的代码本质上是这样的:
递归调用传入指向数组中下一项的指针并减少计数,这是您在递归终止条件中使用的。
Arrays are basically pointers to the start of the first element, so you code is essentially this:
The recursive call is passing in a pointer to the next item in the array and decreasing the count, which is your used in your recursive termination condition.
所以它执行以下操作:
So it does the following:
恕我直言,理解递归的一个好方法是在调试器中运行代码,并观察调用堆栈和变量。
A good way to understand recursion IMHO is to run the code in a debugger, and watch the call stack and variables.
如何打印零大小的数组? 简单:你不需要
这就是您的
if (n<=0) return;
如何打印包含 1 个元素的数组? 简单:只需打印元素 并将其从数组中删除,然后像以前一样打印结果为零大小的数组
这就是您的
printf("%d\n", a[0]);
如何打印包含 2 个元素的数组? 简单:打印第一个元素并将其从数组中删除,然后像以前一样打印生成的单一大小的数组
这就是您的
print(&a[1], n-1);
简单:打印第一个元素,将其从数组中删除,然后打印生成的较小数组
How do you print a zero-sized array? Easy: you don't
That's your
if (n<=0) return;
How do you print an array with 1 element? Easy: just print the element and remove it from the array and print the resulting zero-sized array as before
That's your
printf("%d\n", a[0]);
How do you print an array with 2 elements? Easy: print the first element and remove it from the array and print the resulting one-sized array as before
That's your
print(&a[1], n-1);
Easy: print the first element, remove it from the array, and print the resulting smaller array
如果
n
为零(或更小),则它不执行任何操作,因此递归停止。如果n
> 0,然后打印a[0]
并使用n-1
递归调用自身(对于n
)(这样随着递归的进行,结果会变成 0) ) 和&a[1]
表示a
,即它在每次递归调用中递增指针a
。请记住,C 中的数组参数是指针参数的语法糖。因此,您发布的代码相当于:
If
n
is zero (or less), it does nothing, so recursion stops. Ifn
> 0, then it printsa[0]
and calls itself recursively withn-1
forn
(so that goes to 0 as the recursion proceeds) and&a[1]
fora
, i.e. it increments the pointera
in each recursive call. Remember that an array argument in C is syntactic sugar for a pointer argument.So, the code you posted is equivalent to:
如果您可以自己验证以下算法是否可以打印数组,您应该能够理解为什么 C 代码可以工作,因为它是直接翻译。
打印数组的 n 个元素:
If you can verify to yourself that the following algorithm works to print an array, you should be able to understand why the C code works, since it's a direct translation.
To print n elements of an array:
它相当于一个循环:
为什么?好吧,递归总是查看第一个元素并打印它,然后通过查看第二个元素(现在将是下一次迭代中的“第一个”)中的数组来前进到下一个元素。
您的停止条件是当没有更多元素剩余时 - 即长度为 0 的数组。
it is equivalent to a loop:
why? well, the recursion always looks at the first element and prints it, and them advances to the next element by looking at the array from the 2nd element (which will now be the 'first', in the next iteration).
your stop condition is when no more elements are left - i.e. an array of length 0.
该函数接受一个数组和数组的长度。
如果数组的长度<=0,则函数返回。
打印数组的第一个元素,即元素 0。
&a[1] 获取指向数组第一个元素的指针。数组和指针可以互换使用,因此当将其传递给函数时,函数可以将其视为新数组,从前一个数组的第二个元素开始,长度减一。
The function accepts an array and the length of the array.
If the length of the array is <=0 the function returns.
The first element of the array, element 0 is printed.
&a[1] gets a pointer to the first element of the array. Arrays and pointers are usable interchangably so when this is passed to the function the function can treat it as a new array, starting from the second element of the previous array, and with a length one less.
每次调用 print 都会执行以下操作:
你到底不明白什么?
Each call to print do this :
What exactly don't you understand?