C 关于递归函数的问题?
我有一个C语言书中的递归函数,如下所示:C 关于递归函数的问题?,c,recursion,C,Recursion,我有一个C语言书中的递归函数,如下所示: void print(int a[], int n) { if (n<=0) return ; printf("%d\n", a[0]); print(&a[1], n-1); } void打印(int a[],int n) {如果(n&a[1]是数组第二个元素的地址,它实际上是第一个元素之后的数组部分的地址。因此,在打印参数数组的第一个元素之后 print(&a[1], n-1); 将自身传递给数组的
void print(int a[], int n)
{ if (n<=0) return ;
printf("%d\n", a[0]);
print(&a[1], n-1);
}
void打印(int a[],int n)
{如果(n&a[1]
是数组第二个元素的地址,它实际上是第一个元素之后的数组部分的地址。因此,在打印参数数组的第一个元素之后
print(&a[1], n-1);
将自身传递给数组的其余部分,同时将长度减少1
例如,如果使用数组{1,2,3,4,5}
和n==5
调用print
,则事件和调用链如下所示:
打印第一个元素(1)
用数组的剩余部分调用自己,即{2,3,4,5}
和n==4
打印第一个元素(2)
用数组的剩余部分调用自身,即{3,4,5}
和n==3
打印第一个元素(3)
用数组的剩余部分调用自身,即{4,5}
和n==2
打印第一个元素(4)
使用数组的剩余部分调用自身,即{5}
和n==1
打印第一个元素(5)
用数组的剩余部分调用自身,即{}
和n==0
n返回
返回
返回
返回
返回
返回
如果n
为零(或更小),它什么也不做,因此递归停止。如果n
>0,则它打印a[0]
,并递归调用n
的n-1
(因此随着递归的进行,它会变为0)和&a[1]
用于a
,即在每次递归调用中递增指针a
。请记住,C中的数组参数是指针参数的语法糖
因此,您发布的代码相当于:
void print(int *a, int n)
{
if (n > 0) {
printf("%d\n", *a);
print(a+1, n-1);
}
}
如果您可以验证以下算法是否可以打印数组,那么您应该能够理解为什么C代码可以工作,因为它是直接翻译的
要打印数组的n个元素,请执行以下操作:
- 如果要求您不打印任何元素,请停止打印
- 否则:
- 打印第一个元素,然后
- 打印数组其余部分的n-1个元素(使用相同的配方)
数组基本上是指向第一个元素开头的指针,因此您的代码基本上是这样的:
void print(int *a, int n)
{ if (n<=0) return ;
printf("%d\n", *a);
print(a+1, n-1);
}
void打印(int*a,int-n)
{如果(n如此,它会执行以下操作:
检查数组中是否有元素,如果没有,请返回
打印数组中的第一个元素,因为我们知道至少有一个元素
再次调用自身,指向数组中的第二个元素,并从大小中减去1,从而再次从#1开始
此函数将数组的剩余部分及其包含的元素数作为参数。每次打印第一个元素,然后递归调用剩余部分时,都会使用该参数。以下是一个示例:
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;
每次打印调用都要执行以下操作:
打印数组a的第n个元素,并减少要打印的剩余元素(n)计数。(看着n,就像它意味着:还有多少元素要打印一样)
将指针传递给数组的第二个元素(&a[1])称为自递减(n-1:要打印的元素少了一个),因为第一个元素(a[0])已经打印
您到底不明白什么?理解递归IMHO的一个好方法是在调试器中运行代码,并观察调用堆栈和变量。它相当于一个循环:
int i ;
for (i = 0 ; i< n ; i++) {
printf("%d\n",a[i]);
}
inti;
对于(i=0;i
为什么?递归总是查看第一个元素并打印它,然后通过查看第二个元素的数组(在下一次迭代中,它现在将是“第一个”)将它们前进到下一个元素。
停止条件是不再剩下任何元素,即长度为0的数组。函数接受数组和数组长度
if(n<=0) return;
将打印数组的第一个元素,即元素0
print(&a[1], n-1);
&[1]获取指向数组第一个元素的指针。数组和指针可以互换使用,因此当将其传递给函数时,函数可以将其视为一个新数组,从上一个数组的第二个元素开始,长度减少一个。
- 如何打印零大小的数组?简单:您不需要打印
这就是你的if(nIt)如果你用+1替换&a[1],可能更容易理解——它们的意思是一样的。
print(&a[1], n-1);