鱼C论坛

 找回密码
 立即注册
查看: 2785|回复: 7

C语言递推问题和数组问题

[复制链接]
发表于 2022-11-5 22:59:35 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include<stdio.h>
int a[]={0,1,2,3,4,5,6,7,8,9};
float f(int n){
    if(n==1)
      return a[0];
    else
    return((float)(n*f(n-1)+a[n])/(n+1));
}
int main(){
    int n=10;
    printf("f(%d)=%g\n",n,f(n));
}程序运行后的结果为:
f(10)=4


这题递推怎么等于4,我算出来是等于0,还有数组int a[]={0,1,2,3,4,5,6,7,8,9};那么数组a的下标应该是从0到9,a[10]等于多少,按定义对未指定下标的a[]那a[10]应该等于0吧,还有从(n*f(n-1)+a[n])/(n+1)是从10开始推推到n==1,f(1)=a[0]即0

为什么最后的结果为f(10)=4
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-11-5 23:12:00 | 显示全部楼层
本帖最后由 jackz007 于 2022-11-5 23:16 编辑

        这题最大的问题就是在于元素 a[10] 已经越界,其值并不确定,在这种情况下,不同编译器的编译结果会有所不同
        gcc 编译
D:\[00.Exerciese.2022]\C>g++ -o x x.c

D:\[00.Exerciese.2022]\C>x
 f(10) = 4

D:\[00.Exerciese.2022]\C>
        VC 6 编译
D:\[00.Exerciese.2022]\C>cl x.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

x.c
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:x.exe
x.obj

D:\[00.Exerciese.2022]\C>x
 f(10) = 5.66731e+007

D:\[00.Exerciese.2022]\C>
        可见,用 gcc 编译的 exe 运行结果与楼主一样,是 4,但是,用 VC6 编译 exe 的运行结果却是 5.66731e+007,根源就在 a[10] 是野值上。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-5 23:28:33 | 显示全部楼层
真对不起,算不出来
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-5 23:35:03 | 显示全部楼层
代码左对齐很优秀
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-6 00:03:20 | 显示全部楼层
递推演算最后发现,结果就是(a[10]+a[9]+.......a[2]+0)/11=(44+a[10])/11=4+a[10]/11,这是逻辑结果,实际结果却是4(VS 2017编译),难道真如题主所说a[10]=0?很简单,直接越界输出a[],发现都是0.000000,没记错的话,在VC++中越界输出是一个很大很乱的数,显然,通过这两种方式都可以尽量地避免数组越界问题(由于C语言不检查越界,取极端数字来自查)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-6 07:33:41 | 显示全部楼层
本帖最后由 jhq999 于 2022-11-6 07:36 编辑

为什么要递归,还有a[10]越界,如果最后让a[n]=0的话,可以a[n%10]
int main(void)
{
    int a[]={0,1,2,3,4,5,6,7,8,9},i,j,n;//((float)(n*f(n-1)+a[n])/(n+1));
    float fn=a[0];
    for(n=2;n<11;n+=1)
    {
        printf("%f\n",fn);
        fn=(float)(n*fn+a[n%10])/(n+1);
    }
    printf("%f\n",fn);
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-6 11:19:23 | 显示全部楼层
jhq999 发表于 2022-11-6 07:33
为什么要递归,还有a[10]越界,如果最后让a[n]=0的话,可以a[n%10]

照着你的思路直接循环条件for(n=2;n<10;n++)就万事大吉了,但显然我们并不是在讨论是用循环好还是递归好,而是数组越界取值的问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-6 12:02:58 | 显示全部楼层
本帖最后由 jhq999 于 2022-11-6 12:10 编辑
小鱼儿mxkk 发表于 2022-11-6 11:19
照着你的思路直接循环条件for(n=2;n


大吉啥?n<10,fn值4.4,越界是因为a[n](n=10),楼主那个是全局变量在静态区,自动初始化为0,所以越界a[10]=0;如果是局部变量,初始值谁知道是多少,也fn不可能为4
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-10 15:40

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表