关于函数调用

dikong 2008-10-12 02:53:12
#include<stdio.h>
int f(int a[],int n)
{
if(n>1) return a[0]+f(&a[1],n-1);
else return a[0];
}
main()
{
int aa[3]={1,2,3} ,s;
s=f(&aa[0],3);
printf("%d\n",s);
}
那位高手帮我解释一下程序运行过程。(结果是6)
...全文
334 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
wensheng_zh2007 2008-10-18
  • 打赏
  • 举报
回复
数组还可以这么用!!
学习了,嘿嘿
czbever 2008-10-18
  • 打赏
  • 举报
回复
#include <stdio.h>
int f(int a[],int n)
{
if(n>1) return a[0]+f(&a[1],n-1);
else return a[0];
}
main()
{
int aa[3]={1,2,3} ,s;
s=f(&aa[0],3);
printf("%d\n",s);
}

可以将&a[1]这个当做一个指针,它在递归调用中每次指向的值都是不一样的,第一次指向1,第二次指2,第三次指向3
所以应该是1+2+3=6
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 Chiyer 的回复:]
你对递归了解不,这是个递归求数组元素的和的函数

或者你可以单步跟踪调试一下
[/Quote]
还是自己拿笔算一下吧
elmnd 2008-10-18
  • 打赏
  • 举报
回复
有点意思?只是有点???
我觉得这个用指针解释好过用数组。。。
xqwin 2008-10-17
  • 打赏
  • 举报
回复
a[i]
f(a[1],n-1)中的a[1]是个关键点!它使得f的每次调用的参数都是数组的下一位!
这是一个算法的技巧哦!记得了,下次自己也可以用!!
hctjdx 2008-10-17
  • 打赏
  • 举报
回复
咋好多人多在问这个,是作业吗?
是递归调用是每次a[i]穿过去得是地址,每次带过去得a[1]在子函数就不再是 a[1],而是前移了一位。
hackxq 2008-10-13
  • 打赏
  • 举报
回复
有点不明白
开始调用 f(&a[0],3)
->1+f(&a[1],2) //此时a[0]作为数组首地址,所以a[0] (第一个元素)为1
->2+f(&a[1],1) //此时a[1]作为数组首地址,所以a[0](第一个元素)为2
->a[0] //此时n=1,所以返回a[0](第一个元素)的值,为什么是3?数组的首地址按上一层传
进的参数,不是还是&a[1]吗?
uurabit 2008-10-13
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 wuyu637 的回复:]
第一次函数调用
n = 3,>1;,
进入a[0]+f(&a[1],n-1); 传入的是数组的第二个元素的地址,实际上是2

在下一次函数调用的时候,函数里的数组地址,是从2开始的,a[0]的意思是取距离a这个地址为0的位置的数据。也就是2.
a[0]+f(&a[1],3-1); -----------》 这里a'【0】 = 2; a'[1]=3;.由于函数的参数传递是拷贝传递,也就是说,a和a'实际上不是一个
n = 3-1 =2;,> 1;

int f(in…
[/Quote]
Big鹏 2008-10-13
  • 打赏
  • 举报
回复

#include <stdio.h>
int f(int a[],int n)
{
if(n>1)
return a[0]+f(&a[1],n-1);
else
return a[0];
}
main()
{
int aa[3]={1,2,3},s;
s=f(&aa[0],3);
printf("%d\n",s);
}
第一次,n=3 >1,所以,return a[0]+f(&a[1],n-1) 即:1+f(2,2);
第二次,此时仅看1+f(2,2)中的f(2,2)。因为:n=2 >1,所以,再次:return a[0]+f(&a[1],n-1)即:2+f(2,1);
此处要注意的是a[0]=2。
第三次,方法同上,但是要注意的是a[0]=3;
最后,依次递推回去,就是3+2+1=6.
ivan8222 2008-10-13
  • 打赏
  • 举报
回复
求和
lbjfeng 2008-10-13
  • 打赏
  • 举报
回复
递归调用,
其实,第一次返回:a[0]+f(&a[1],2)
第二次返回:a[1]+f(&a[1],2)
第三次返回:a[2]
结果就是a[0] + a[1] + a[2] = 6
太乙 2008-10-13
  • 打赏
  • 举报
回复


#include <stdio.h>
int f(int a[],int n)
{
if(n>1) return a[0]+f(&a[1],n-1);
else return a[0];
}
main()
{
int aa[3]={1,2,3} ,s;
s=f(&aa[0],3);
printf("%d\n",s);
}



画画图:

main: f(a,3):

进入f函数体,执行if(3>1)
应该返回 a[0]+f(&a[1],2):

也就是:

f(a,3) = a[0]+f(&a[1],2)
^
|
|
|
|
|
a[1]+f(&a[2],1)
^
|
|
|
|
a[2]//因为n==1,所以直接返回a[2];

然后倒回去:


也就是:a[0]+a[1]+a[2]

不知道够不够清楚!

pingzi_1119 2008-10-13
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 wuyu637 的回复:]
第一次函数调用
n = 3,>1;,
进入a[0]+f(&a[1],n-1); 传入的是数组的第二个元素的地址,实际上是2

在下一次函数调用的时候,函数里的数组地址,是从2开始的,a[0]的意思是取距离a这个地址为0的位置的数据。也就是2.
a[0]+f(&a[1],3-1); -----------》 这里a'【0】 = 2; a'[1]=3;.由于函数的参数传递是拷贝传递,也就是说,a和a'实际上不是一个
n = 3-1 =2;,> 1;

int f(in…
[/Quote]
up
zzhzhua 2008-10-13
  • 打赏
  • 举报
回复
对递归的理解就像是剥开层层包裹的纸团,要一层层的向下剥开,知道循环结束为止,在反推回去就可以了。
野男孩 2008-10-13
  • 打赏
  • 举报
回复
每递归调用一次,参数中的数组a已经不是原来的数组a了,而是a+1

[Quote=引用 13 楼 hackxq 的回复:]
有点不明白
开始调用 f(&a[0],3)
->1+f(&a[1],2) //此时a[0]作为数组首地址,所以a[0] (第一个元素)为1
->2+f(&a[1],1) //此时a[1]作为数组首地址,所以a[0](第一个元素)为2
->a[0] //此时n=1,所以返回a[0](第一个元素)的值,为什么是3?数组的首地址按上一层传
进的参数,不是还是&a[1]吗?
[/Quote]
emailtome 2008-10-13
  • 打赏
  • 举报
回复
这样是不是好理解些


#include <stdio.h>

int f(int*p,int n);

int main()
{
int aa[3]={1,2,3} ,s;
s=f(&aa[0],3);
printf("%d\n",s);
return 0;
}

int f(int*p,int n)
{
if(n>1)
return *p +f(p=p+1,n-1);
else
return 1;
}

jia_xiaoxin 2008-10-13
  • 打赏
  • 举报
回复
main()
{
int aa[3]={1,2,3} ,s;
//s = f(&aa[0],3);
if(3>1)
//return a[0]+f(&a[1],3-1);
return a[0] + A; //这里的A就是f(&a[1],3-1);
else
return a[0];

printf("%d\n",s);
}

A:
展开 f(&a[1],3-1);
if(3-1 > 1)
//return a[0] + f(&a[1],3-1-1);
return a[0] + B; //这里的B就是f(&a[1],3-1-1);
else
return a[0];

B:
展开 f(&a[1],3-1-1);
if(3-1-1 > 1) //此时条件不满足,不再进行递归
//return a[0] + f(&a[1],3-1-1-1);
return a[0] + C; //这里的C就是f(&a[1],3-1-1-1);
else
return a[0]; //执行这条语句,使B的返回值为a[0],也就是3.就相当于B=3;此时的a[0]是以&a[2]为首地址

返回后此时A就变为:
if(3-1 > 1)
//return a[0] + f(&a[1],3-1-1);
return a[0] + 3; //执行这条语句,使A的返回值为a[0] + 3,就相当于A=5;此时的a[0]是以&a[1]为首地址
else
return a[0];

返回后就到了主程序
//s = f(&aa[0],3);
if(3>1)
//return a[0]+f(&a[1],3-1);
return a[0] + 5; //A的返回值为a[0] + 5,就相当于s=6;此时的a[0]是以&a[0]为首地址
else
return a[0];

此时的返回值就s也就是6。
derek02 2008-10-13
  • 打赏
  • 举报
回复
递归,自己调用自己。。。。。
zgjxwl 2008-10-12
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 Chiyer 的回复:]
你对递归了解不,这是个递归求数组元素的和的函数

或者你可以单步跟踪调试一下
[/Quote]
另外递归需要注意的两点:
1:递推 将原问题不断的分解,从未知向已知递推
2:回归 从已知条件出发,回归到递推的开始处

把握这个,再进行跟踪调试下就明白了
aaa7782814 2008-10-12
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 laoshizheyangzi 的回复:]
意思就是1+2+3等于6
[/Quote]
就是这个理儿
加载更多回复(10)

70,037

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧