关于递归函数的问题?

发布于 2024-10-26 22:05:22 字数 243 浏览 2 评论 0原文

我有一个来自 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

还在原地等你 2024-11-02 22:05:22

&a[1] 是数组第二个元素的地址,它实际上是数组中第一个元素之后的部分的地址。因此,在打印参数数组的第一个元素后,

print(&a[1], n-1);

将数组的剩余部分传递给自己,同时将长度减一。

例如,如果您使用数组 {1, 2, 3, 4, 5}n == 5 调用 print,则链事件和调用如下:

  1. 打印第一个元素 (1)
  2. 调用自身以及数组的其余部分,即 {2, 3, 4, 5}n == 4
    1. 打印第一个元素 (2)
    2. 使用数组的剩余部分调用自身,即 {3, 4, 5}n == 3
      1. 打印第一个元素 (3)
      2. 使用数组的剩余部分调用自身,即 {4, 5}n == 2
        1. 打印第一个元素 (4)
        2. 使用数组的剩余部分调用自身,即 {5}n == 1
          1. 打印第一个元素 (5)
          2. 使用数组的剩余部分调用自身,即 {}n == 0
            1. n<=0 ->返回
          3. 返回
        3. 返回
      3. 返回
    3. 返回
  3. 返回

&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,

print(&a[1], n-1);

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} and n == 5, the chain of events and calls is the following:

  1. print the first element (1)
  2. call itself with the remaining portion of the array, i.e. {2, 3, 4, 5} and n == 4
    1. print the first element (2)
    2. call itself with the remaining portion of the array, i.e. {3, 4, 5} and n == 3
      1. print the first element (3)
      2. call itself with the remaining portion of the array, i.e. {4, 5} and n == 2
        1. print the first element (4)
        2. call itself with the remaining portion of the array, i.e. {5} and n == 1
          1. print the first element (5)
          2. call itself with the remaining portion of the array, i.e. {} and n == 0
            1. n<=0 -> return
          3. return
        3. return
      3. return
    3. return
  3. return
夏末的微笑 2024-11-02 22:05:22

该函数将数组的剩余部分及其包含的元素数量作为参数。每次打印第一个元素,然后递归调用其余部分。这是一个例子:

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;

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:

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;
烟酒忠诚 2024-11-02 22:05:22

数组基本上是指向第一个元素开头的指针,因此您的代码本质上是这样的:

void print(int *a, int n)
{   if (n<=0)  return ;
     printf("%d\n", *a);
     print(a+1, n-1);
}

递归调用传入指向数组中下一项的指针并减少计数,这是您在递归终止条件中使用的。

Arrays are basically pointers to the start of the first element, so you code is essentially this:

void print(int *a, int n)
{   if (n<=0)  return ;
     printf("%d\n", *a);
     print(a+1, n-1);
}

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.

时间你老了 2024-11-02 22:05:22

所以它执行以下操作:

  1. 检查数组中是否有元素,如果没有,则返回。
  2. 打印数组中的第一个元素,因为我们知道至少有一个元素。
  3. 再次调用自身,指向数组中的第二个元素,并从大小中减去 1,从而再次从 #1 开始。

So it does the following:

  1. Check if there are any elements in the array, if not, just return.
  2. Print the first element in the array since we know we have atleast one.
  3. Calls itself again pointing to the 2nd element in the array, and subtracting 1 from the size, thus starting at #1 again.
厌倦 2024-11-02 22:05:22

恕我直言,理解递归的一个好方法是在调试器中运行代码,并观察调用堆栈和变量。

A good way to understand recursion IMHO is to run the code in a debugger, and watch the call stack and variables.

九命猫 2024-11-02 22:05:22
  • 如何打印零大小的数组? 简单:你不需要
    这就是您的 if (n<=0) return;

  • 如何打印包含 1 个元素的数组? 简单:只需打印元素 并将其从数组中删除,然后像以前一样打印结果为零大小的数组
    这就是您的 printf("%d\n", a[0]);

  • 如何打印包含 2 个元素的数组? 简单:打印第一个元素将其从数组中删除,然后像以前一样打印生成的单一大小的数组
    这就是您的 print(&a[1], n-1);


  • 如何打印包含 N 个元素的数组?
    简单:打印第一个元素,将其从数组中删除,然后打印生成的较小数组
  • 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);


  • How do you print an array with N elements?
    Easy: print the first element, remove it from the array, and print the resulting smaller array
梦在夏天 2024-11-02 22:05:22

如果n为零(或更小),则它不执行任何操作,因此递归停止。如果n> 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);
    }
}

If n is zero (or less), it does nothing, so recursion stops. If n > 0, then it prints a[0] and calls itself recursively with n-1 for n (so that goes to 0 as the recursion proceeds) and &a[1] for a, i.e. it increments the pointer a 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:

void print(int *a, int n)
{
    if (n > 0) {
        printf("%d\n", *a);
        print(a+1, n-1);
    }
}
成熟的代价 2024-11-02 22:05:22

如果您可以自己验证以下算法是否可以打印数组,您应该能够理解为什么 C 代码可以工作,因为它是直接翻译。

打印数组的 n 个元素:

  • 如果要求您不打印任何元素,请停止。
  • 否则:
    • 打印第一个元素,然后
    • 打印数组其余部分的 n-1 个元素(使用相同的方法)。

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:

  • If you're asked to print no elements, just stop.
  • Otherwise:
    • Print the first element, and then
    • Print n-1 elements of the rest of the array (using this same recipe).
骄傲 2024-11-02 22:05:22

它相当于一个循环:

int i ;
for (i = 0 ; i< n ; i++) { 
printf("%d\n",a[i]);
}

为什么?好吧,递归总是查看第一个元素并打印它,然后通过查看第二个元素(现在将是下一次迭代中的“第一个”)中的数组来前进到下一个元素。

您的停止条件是当没有更多元素剩余时 - 即长度为 0 的数组。

it is equivalent to a loop:

int i ;
for (i = 0 ; i< n ; i++) { 
printf("%d\n",a[i]);
}

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.

抠脚大汉 2024-11-02 22:05:22

该函数接受一个数组和数组的长度。

if(n<=0) return;

如果数组的长度<=0,则函数返回。

printf("%d\n", a[0]);

打印数组的第一个元素,即元素 0。

print(&a[1], n-1);

&a[1] 获取指向数组第一个元素的指针。数组和指针可以互换使用,因此当将其传递给函数时,函数可以将其视为新数组,从前一个数组的第二个元素开始,长度减一。

The function accepts an array and the length of the array.

if(n<=0) return;

If the length of the array is <=0 the function returns.

printf("%d\n", a[0]);

The first element of the array, element 0 is printed.

print(&a[1], n-1);

&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.

旧情别恋 2024-11-02 22:05:22

每次调用 print 都会执行以下操作:

  1. 打印数组 a 的第 n 个元素,并递减要打印的剩余元素 (n) 计数。(看 n 的意思:还有多少个元素要打印)。
  2. 将其称为自减(n - 1:少一个要打印的元素),将指针传递给数组的第二个元素 (&a[1]),因为第一个元素 (a[0]) 已被打印。

你到底不明白什么?

Each call to print do this :

  1. print the n-th element of the array a and decrement the remaining elements (n) count to print.(Look at n like it means: how many elements remain to print).
  2. Call it self decrementing (n - 1 : one less element to print) passing a pointer to the second element of the array (&a[1]) because the first element (a[0])has already be printed.

What exactly don't you understand?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文