鱼C论坛

 找回密码
 立即注册
查看: 3650|回复: 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
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

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

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

  4. D:\[00.Exerciese.2022]\C>
复制代码

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

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

  7. /out:x.exe
  8. x.obj

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

  11. D:\[00.Exerciese.2022]\C>
复制代码

        可见,用 gcc 编译的 exe 运行结果与楼主一样,是 4,但是,用 VC6 编译 exe 的运行结果却是 5.66731e+007,根源就在 a[10] 是野值上。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-5 23:28:33 | 显示全部楼层
真对不起,算不出来
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-5 23:35:03 | 显示全部楼层
代码左对齐很优秀
小甲鱼最新课程 -> https://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语言不检查越界,取极端数字来自查)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

为什么要递归,还有a[10]越界,如果最后让a[n]=0的话,可以a[n%10]
  1. int main(void)
  2. {
  3.     int a[]={0,1,2,3,4,5,6,7,8,9},i,j,n;//((float)(n*f(n-1)+a[n])/(n+1));
  4.     float fn=a[0];
  5.     for(n=2;n<11;n+=1)
  6.     {
  7.         printf("%f\n",fn);
  8.         fn=(float)(n*fn+a[n%10])/(n+1);
  9.     }
  10.     printf("%f\n",fn);
  11.     return 0;
  12. }
复制代码
小甲鱼最新课程 -> https://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++)就万事大吉了,但显然我们并不是在讨论是用循环好还是递归好,而是数组越界取值的问题
小甲鱼最新课程 -> https://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
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-14 18:17

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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