printf("%d",fun(i));
}
intfun(intn)
{
if(___1___)
return0;
else
if(___2___)
return1;
else
return___3___;
}
3
题目:
请补充函数fun(char*s),该函数的功能是把字符串中的内容逆置。
例如:
字符串中原有的字符串为abcde,则调用该函数后,串中的内容为edcba。
注意:
部分源程序如blank.c给出。
请勿改动主函数main和其他函数中的任何内容,仅在fun函数的横线上填入所编写的若干表达式或语句。
#include
#include
#include
#defineN81
voidfun(char*s)
{
inti=0,t,n=strlen(s);
for(;___1___;i++)
{
t=*(s+i);
___2___;
___3___;
}
}
main()
{
chara[N];
clrscr();
printf("Enterastring:
");
gets(a);
printf("Theoriginalstringis:
");
puts(a);
fun(a);
printf("\n");
printf("Thestringaftermodified:
");
puts(a);
}
4
题目:
请补充函数fun,它的功能是:
计算并输出n(包括n)以内能被3或7整除的所有自然数的倒数之和。
例如,在主函数中从键盘给n输入30后,输出为:
s=1.226323。
注意:
部分源程序如blank.c给出。
请勿改动主函数main和其他函数中的任何内容,仅在fun函数的横线上填入所编写的若干表达式或语句。
#include
doublefun(intn)
{
inti;
doublesum=0.0;
if(n>0&&n<=100)
{
for(i=1;___1___;i++)
if(___2___)
sum+=___3___;
}
returnsum;
}
main()
{
intn;
doubles;
printf("\nInputn:
");
scanf("%d",&n);
s=fun(n);
printf("\n\ns=%f\n",s);
}
淘宝网大甩卖快快加入吧
淘宝结婚季-最赞美肌宝典玩转新奇音响我是一只与世无争的猪说对不起太难,小礼物帮你忙!
办公室咖啡杯情缘夏日宝贝计划施华洛世奇09夏季新款
解答
1
分析:
整个程序是计算10的阶乘,而n的阶乘是这样计算的:
n!
=n*(n-1)*(n-2)*(n-3)*…*3*2*1
其中n>0并且n为自然数。
所以,10的阶乘就是计算10*9*8*7*6*5*4*3*2*1的结果,换句话说就是计算1至10之间所有自然数的乘积。
从程序来看,fun函数就是计算阶乘的函数,但是在fun函数中又调用了自己,即第五行"return(n*fun(___2___));"中fun函数又调用了fun函数,这种函数自己调用自身的现象在程序设计中称为递归,使用递归这种程序设计方法对设计人员的程序设计能力有较高的要求。
计算阶乘是递归程序设计的一个经典示例。
计算某个数的阶乘就是用那个数去乘包括1在内的所有比它小的数。
例如,fun(5)等价于5*4*3*2*1,而fun(3)等价于3*2*1。
阶乘的一个有趣特性是,某个数的阶乘等于起始数(startingnumber)乘以比它小一的数的阶乘。
例如,fun(5)与5*fun(4)相同。
您很可能会像这样编写阶乘函数fun:
intfun(intn)
{
returnn*fun(n-1);
}
不过,这个函数的问题是,它会永远运行下去,因为它没有终止的地方。
函数会连续不断地调用fun。
当计算到零时,没有条件来停止它,所以它会继续调用零和负数的阶乘。
因此,我们的函数需要一个条件,告诉它何时停止。
由于小于1的数的阶乘没有任何意义,所以我们在计算到数字1的时候停止,并返回1的阶乘(即1)。
因此,真正的递归函数类似于:
intfun(intn)
{
if(n==1)
{
return1;
}
else
{
returnn*fun(n-1);
}
}
2
分析:
从题意可以得知本题计算的是斐波纳契数列,斐波纳契数列的计算方法由题目得知该数列中每数等于前面两数之和,如011235813……,这样我们可以列出以下计算斐波纳契数列的公式:
fun(0)=0当n=0
fun
(1)=1当n=1
fun(n)=fun(n-1)+fun(n-2)当n>1
当n等于0的时候,即计算斐波纳契数列的第一个数字,根据题目知道该数列的第一个数字为0。
当n等于1的时候,即计算斐波纳契数列的第二个数字,根据题目知道该数列的第二个数字为1。
当n等于2的时候,即计算斐波纳契数列的第三个数字,由于该数列中每数等于前面两数之和,所以fun
(2)=fun
(1)+fun(0)。
当n等于3的时候,即计算斐波纳契数列的第四个数字,由于该数列中每数等于前面两数之和,所以fun(3)=fun
(2)+fun
(1)。
……
所以当n大于1的时候,fun(n)=fun(n-1)+fun(n-2)。
这里存在函数调用本身的现象,这种现象在程序设计中称为递归。
3
分析:
将字符串中的内容逆置主要思路分析如下:
(1)在字符串第一个字母位置和最后一个字母位置各自设置一个指示器A和B,它们分别指向第一个字母和最后一个字母,然后A位置的字母和B位置的字母进行互换。
(2)互换结束之后指示器A移动到第二个字母,而指示器B移动到倒数第二个字母,即指示器A往后移动一个字母位置,而指示器B往前移动一个字母位置,然后A位置的字母和B位置的字母进行互换。
(3)互换结束之后指示器A往后再次移动一个字母位置,而指示器B再次往前移动一个字母位置,然后A位置的字母和B位置的字母进行互换。
(4)以上过程反复进行,只有指示器B的位置小于指示器A的位置,即指示器B指向的位置在指示器A指向的位置的左边的情况下才结束,所以以上过程可以使用循环语句实现,循环终止条件可以判断指示器B的位置是否小于指示器A的位置。
为了实现以上思路,我们观察fun函数。
fun函数的功能就是将传入的s参数作为字符串进行内容逆置,它的逆置方法和我们分析的思路是一致的。
它使用了for循环语句进行循环,循环体中使用指针s+i作为指示器A,而指示器B使用s+n-1-i表示。
其中i每次循环加一,而n=strlen(s),为传入的字符串的长度。
strlen函数可以得到s参数的字符串中包含的字母个数。
为什么指针s+i可以作为指示器A呢?
由于指针s对应main函数传入的a数组,而C语言中数组名称就是一个指向数组第一个元素的指针,所以数组a的名称a就是一个char类型的指针,即为char*a;。
所以指针s指向传入的字符串的第一个字母,所以可以使用s作为指示器A的初始值。
而每次循环i都加一,在C语言语法中,一个指针加上一个整数表示一个新指针,该指针指向原指针向后移动所加上整数个数的位置,所以s+1指向字母"b",s+2指向字母"c",依次类推。
那为什么s+n-1-i可以作为指示器B呢?
如果传入的字符串为"abcde",s指针指向字母"a",n为字符串为"abcde"的长度,即字符串"abcde"的字母个数,即为5。
一个指针加上一个整数表示一个新指针,该指针指向原指针向后移动所加上整数个数的位置,所以s+5表示指向从字母"a"向后移动5个位置的新指针,即字母"e"后面一个位置,而我们希望指示器B指向字母"e",所以s+n-1才是指示器B的初始值。
每次循环i都加一,在C语言语法中,一个指针减去一个整数表示一个新指针,该指针指向原指针向前移动所减去整数个数的位置。
例如s+n-1指向字母"e",s+n-1-1指向字母"d",s+n-1-2指向字母"c",依次类推。
进行逆置的for循环终止条件是判断指示器A的位置是否在指示器B的位置的右边,那么循环继续的条件就是指示器A的位置应该在指示器B的位置的左边。
根据C语言的语法,指针P1在指针P2的左边可以使用P1所以fun函数第一个填空处应该填写指示器A<指示器B,即s+i
分析到这里,fun函数剩下的两个填空应该填写什么呢?
for循环体中应该进行指示器A和指示器B两个位置的字母互换。
t=*(s+i);语句先把指示器A位置的字母保存在t变量中,然后将指示器B位置的字母覆盖指示器A位置的字母,然后将预先保留在t变量中的指示器A位置的字母覆盖指示器B位置的字母,这样即完成两个位置的字母互换。
根据C语言的语法,取得指针指向位置的值应该使用*运算符。
所以指示器A位置的字母使用*(s+i)表示,而指示器B位置的字母使用*(s+n-1-i)表示,所以第二处填空处应该填写*(s+i)=*(s+n-1-i),而第三处填空处应该填写*(s+n-1-i)=t。
程序注解如下:
#include
#include
#include
#defineN81
/*fun函数的功能是把字符串中的内容逆置*/
voidfun(char*s)
{
/*定义存放要逆置的字符串的字符数组*/
inti=0,t,n=strlen(s);
for(;s+i
{
t=*(s+i);
*(s+i)=*(s+n-1-i);
*(s+n-1-i)=t;
}
}