weixin_46147489
2021-01-31 11:28
采纳率: 100%
浏览 59

在C语言中用二维数组输出直角杨辉三角形,数组的初始化与否为何会影响数组的输出结果?

大神们好!!

问题如题所示。

  • 首先,可以正确输出数组结果的代码如下:
  • #include<stdio.h>
    int main(void)
    {
            int m,n;
            int a[20][20];                          //数组初始化
            for(m=0;m<20;m++){
                    for(n=0;n<20;n++){
                            a[m][n]=0;
                    }
            }
            
            int row;
            printf("please input row number:");
            scanf("%d",&row);                       //通过输入指定输出的三角形行数
    
            int i,j;                                //声明行、列下表变量
            for(i=0;i<row;i++){                     //外循环,控制行
                    for(j=0;j<=i;j++){              //内循环,控制列,循环条件为元素的列下标小于等于元素的行下标
                            if(j==0||i==j){         //垂直边和斜边为1的条件
                                    a[i][j]=1;
                            }else{
                                    a[i][j]=a[i-1][j-1]+a[i-1][j];//除了垂直边和斜边的元素
                            }
                    printf("%4d",a[i][j]);          //输出
                    }
            printf("\n");
            }
    
            return 0;
    }
    
  • 正确的输出结果
  •  

  • 然后我把数组初始化的这一部分代码删掉,只定义二维数组:
  • #include<stdio.h>
    int main(void)
    {
    
            int row;
            printf("please input row number:");
            scanf("%d",&row);                       //通过输入指定输出的三角形行数
    
            int i,j;                                //声明行、列下表变量
            int a[i][j];                            //定义二维数组
            for(i=0;i<row;i++){                     //外循环,控制行
                    for(j=0;j<=i;j++){              //内循环,控制列,循环条件为元素的列下标小于等于元素的行下标
                            if(j==0||i==j){         //垂直边和斜边为1的条件
                                    a[i][j]=1;
                            }else{
                                    a[i][j]=a[i-1][j-1]+a[i-1][j];//除了垂直边和斜边的元素
                            }
                    printf("%4d",a[i][j]);          //输出
                    }
            printf("\n");
            }
    
            return 0;
    }
    
  • 然后问题来了! TT:

      为何从第4行开始,每行的第3个元素到斜边之间元素都是a[i][j]=a[i+1][j-1]+a[i+1][j]?(正确的应该是a[i][j]=a[i-1][j-1]+a[i][j-1])

本人初学小白,望大神们指点,感激不尽! TT

  • 点赞
  • 收藏

8条回答 默认 最新

  • 八云黧 2021-01-31 12:13
    已采纳

    这不是数组初始化的问题,而是声明的问题,因为你的int i,j是未初始化的变量,值是系统自动分配的,而你声明a的时候使用了变量i,j,导致你的数组的长和宽变成了随机的数值,运行结果也就和这种随机有关,我试验了一下,当i被分配到一个大数字的时候,j被分配到0的时候就会出现你这样的错误;而在我的电脑上跑的时候分配到0,j分配到了一个大数字,结果是根本运行不来,会产生段错误。

    int a[20][20]是一个数组声明,而下面的循环才是数组初始化,事实上你的想法是对的,不经过初始化的也是可以使用的,但你的声明却用到了未初始化的整型变量,如果你直接使用a[20][20]结果就正确了。

    事实上直接使用20是一种预先分配的思想,但是不足以应对变化,你可以通过输入的行数精确计算出需要的数组长宽然后再进行声明,这样就不会出现当数组某一维度超过20而能产生的越界异常。当然,你也可以预先定义成100000这样一个较大的数字,一般情况也足以满足使用。

    点赞 打赏 评论
  • weixin_46147489 2021-01-31 12:33

    emm.....感谢大神的回答,按照你的建议这边试了一下,定义数组时将下标标量初始化就好了!但是还是想再麻烦请教一下,我这边的错误结果,即a[i][j]=a[i+1][j-1]+a[i+1][j],而不是a[i][j]=a[i-1][j-1]+a[i][j-1],是因为我定义数组时使用没有初始化的下标变量i,g导致的?会有这么巧合的事情?

    (为啥采纳不了?)

    点赞 打赏 评论
  • 八云黧 2021-01-31 12:56

    C语言的编译和运行过程我不太懂,个人感觉和二维数组的越界访问有关,而且这不是巧合,而是必然。如果你把数组a声明为a[20][0],就会复刻这个奇怪的现象,如果你声明为a[0][20],就会产生段错误报错。而i,j具体初始化问什么值适合编译器和机器有关系的,我看到你这个问题第一次跑的时候就是段错误,如果你的编译器把i和j都初始化为一个43333145这么大的数,你甚至都不会遇到问题,换句话说巧不巧合得看运行环境

    点赞 打赏 评论
  • 八云黧 2021-01-31 13:10

    顺便一提,我又在网上查了一下,这好像是和零长度的数组有关,但是长度为0的数组是被标准C和C++禁用的,所以具体的运行原理没什么资料,反正以后注意任何数据都要初始化就行了

    点赞 打赏 评论
  • weixin_46147489 2021-01-31 13:16

    感谢!越来越复杂了。。

    点赞 打赏 评论
  • weixin_46147489 2021-01-31 13:17

    另外,你的回答我这里点击采纳显示错误,已经提交客服了

     

    点赞 打赏 评论
  • 八云黧 2021-01-31 14:28

    没啥好复杂的啊,我给你捋捋。

    导致问题出现的原因是声明数组时使用了未初始化的整型变量作为长度

    解决问题的办法是数组声明时给定数值,可以预定数值或者根据计算赋值

    如果你只是想解决问题并且以后都不遇见这类问题,只要注意初始化,到这就够了。

    当然,问题本身有一个有趣的现象,引出了另一个问题:数组长度取值i,j带来的影响

    我刚才又对i、j的取值进行了测试,结果越来越复杂了,比我刚才说的还复杂,我跑出过段错误,跑出过总线错误,跑出过和你一样的错误结果,跑出过和你类似但不一样的错误结果。。。很显而易见,这些现象的出现和C语言编译器的优化和执行有很大关系,我对C语言运行不太了解,也只能研究到这,你有兴趣有时间可以自己研究一下

     

    点赞 打赏 评论
  • weixin_46147489 2021-01-31 17:37

    哈哈,我说的复杂指的就是用变量i,j产生的那个问题,感谢你啊~

    点赞 打赏 评论

相关推荐 更多相似问题