鱼C论坛

 找回密码
 立即注册
查看: 1602|回复: 4

[已解决]SOS:用C编写函数出现错误,求解决~

[复制链接]
发表于 2019-3-14 11:49:10 | 显示全部楼层 |阅读模式

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

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

x
函数要求1:编写函数 int mergearr( int a[], int m, int b[], int n),将两个严格增序数组a[],b[]合并,并保证合并后数组严格增序,函数值返回合并后的数组a[]中元素个数。
函数要求2:不能定义额外新数组
由于本人才开始学习C,经常出现各种BUG,却不知道错在哪,请各位大佬帮忙~
本人思路文字描述:将b[]中小于a[i]的元素按序插入数组a,大于a[m]的元素插入a[]尾部。

        i=0,j=0;
        a[i]与b[j]进行循环对比(i<a[]长度,j<b[]长度):
        1,如果a[i]<b[j]时,a[i]位置不变,i++后重新对比;
        2,如果a[i]=b[j]时,a[i]不变,i++;j++后重新对比;
        3,如果a[i]>b[j]时,数组a[]中第【i】位元素之后整体后移一位,再将b[j]赋值给a,数组a[]长度++;j++后重新对比。
        循环后两种情况:
        1,数组a[]包含所有数组b[]元素,实现函数要求。
        2,数组a[]未包含所有b[]元素,需要将数组b[]剩余元素插入数组a[]尾部,实现函数要求。


  1. #include<stdio.h>
  2. int mergearr(int a[],int m,int b[],int n)
  3. {
  4.         int i=0,j=0,k,len=m;//m是数组a[]初始长度,len是a[]可变长度。
  5.         printf("函数内m=%d,n=%d\n",m,n);//验证函数各项数值,可忽略。
  6.         while(i<len&&j<n)//while循环逐一判断数组a,b中的元素大小
  7.         {
  8.                 if(a[i]<b[j])
  9.                 {
  10.                         i++;
  11.                 }
  12.                 else if(a[i]==b[j])
  13.                 {
  14.                         i++;j++;
  15.                 }
  16.                 else if(a[i]>b[j])
  17.                 {
  18.                         for(k=len;k>i;k--)//数组a[]从a[i]之后整体后移
  19.                         {
  20.                                 a[k]=a[k-1];
  21.                         }
  22.                         a[i]=b[j];//插入b[j]
  23.                         len++;
  24.                         j++;
  25.                 }
  26.         }
  27.         printf("j=%d,a[len-1]=%d,b[j]=%d,len=%d\n",j,a[len-1],b[j],len);//验证函数各项数值,可忽略。
  28.         while(a[len-1]<b[j]&&j<n)//循环判断数组a[]是否包含全部数组b[],并将剩余数组b[]元素插入数组a[]尾部。
  29.         {
  30.                 a[len]=b[j];
  31.                 len++;
  32.                 j++;
  33.         }
  34.         printf("j=%d,a[len-1]=%d,b[j]=%d,len=%d\n",j,a[len-1],b[j],len);//验证函数各项数值,可忽略。
  35.         printf("函数内m=%d,n=%d\n",m,n);//验证函数各项数值,可忽略。
  36.         for(i=0;i<len;i++)
  37.         {
  38.                 printf("%d,\n",a[i]);
  39.         }
  40.         return len;
  41. }
  42. int main()
  43. {
  44.         int i,j,p,q,length;
  45.         int c[]={1,2,3,5,7,9};
  46.         int d[]={2,4,5,6,8,9,10};
  47.         p=sizeof(c)/sizeof(c[0]);//求c[]长度
  48.         q=sizeof(d)/sizeof(d[0]);
  49.         printf("调用前p=%d,q=%d\n",p,q);//验证函数各项数值,可忽略
  50.         int mergearr(int a[],int m,int b[],int n);
  51.         length=mergearr(c,p,d,q);
  52.         printf("length=%d\n",length);
  53.         printf("调用后p=%d,q=%d\n",p,q);//验证函数各项数值,可忽略
  54.         for(i=0;i<length;i++)
  55.         {
  56.                 printf("%d,",c[i]);
  57.         }
  58. }
复制代码


输出结果如下:
[/i][/i][/i][/i][/i][/i][/i] QQ截图20190314113903.png 这里:调用后p=10,以及最后输出的结果1,2,3,4,5,6,7,8,10,10均不是想要的答案,却不知道在哪里出错,如何更改,请各位大佬帮忙。

最佳答案
2019-3-14 14:13:52
本帖最后由 jackz007 于 2019-3-14 14:17 编辑
路易大魔王 发表于 2019-3-14 13:29
emmmm  有两个地方不明白,第一个是为何用const,第二个是我将函数替换我原来函数之后,p和q的值依然发生 ...


    main() 函数中对 c[] 定义的时候,没有为 d[] 预留空间,导致拼接后 c[] 严重越界
  1.         int c[]={1,2,3,5,7,9};
复制代码

    所以,我对 main() 也做了修改:
  1. #include <stdio.h>

  2. mergearr(int a[] , const int m , const int b[] , const int n)
  3. {
  4.         int i = 0 , j = 0 , k                               ;
  5.         for(i = 0 ; i < n ; i ++) a[m + i] = b[i]           ;
  6.         for(i = 1 ; i < m + n ; i ++) {
  7.                 j = i                                       ;
  8.                 while(j > 0 && a[j] < a[j - 1]) {
  9.                         k = a[j]                            ;
  10.                         a[j] = a[j - 1]                     ;
  11.                         a[j - 1] = k                        ;
  12.                         j --                                ;
  13.                 }
  14.         }
  15.         for(i = 0 ; i < m + n ; i ++) printf("%d\n" , a[i]) ;
  16.         return m + n                                        ;
  17. }

  18. main(void)
  19. {
  20.         int i , j , p , q , length                           ;
  21.         int c[20] = {1 , 2 , 3 , 5 , 7 , 9}                  ;
  22.         int d[] ={2 , 4 , 5 , 6 , 8 , 9 , 10}                ;
  23.         p = 6                                                ; // 求c[]长度
  24.         q = sizeof(d) / sizeof(int)                          ;
  25.         printf("调用前 p = %d , q = %d\n" , p , q)           ; //验证函数各项数值,可忽略
  26.         length = mergearr(c , p , d , q)                     ;
  27.         printf("length = %d\n" , length)                     ;
  28.         printf("调用后 p = %d , q = %d\n" , p , q)           ; //验证函数各项数值,可忽略
  29.         for(i = 0 ; i < length ; i ++) printf("%d ," , c[i]) ;
  30. }
复制代码

        const 的意思是变量在函数内只读,不允许修改,编译程序在检查语法的时候会更加严格。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2019-3-14 12:36:20 | 显示全部楼层
本帖最后由 jackz007 于 2019-3-14 12:42 编辑

    我重写了 mergearr() 楼主可以对照参考
  1. mergearr(int a[] , const int m , const int b[] , const int n)
  2. {
  3.         int i = 0 , j = 0 , k                               ;
  4.         for(i = 0 ; i < n ; i ++) a[m + i] = b[i]           ; // 合并两个数组
  5.         for(i = 1 ; i < m + n ; i ++) {                       // 对合并后的数组排序
  6.                 j = i                                       ;
  7.                 while(j > 0 && a[j] < a[j - 1]) {
  8.                         k = a[j]                            ;
  9.                         a[j] = a[j - 1]                     ;
  10.                         a[j - 1] = k                        ;
  11.                         j --                                ;
  12.                 }
  13.         }
  14.         for(i = 0 ; i < m + n ; i ++) printf("%d\n" , a[i]) ; // 输出
  15.         return m + n                                        ;
  16. }
复制代码

      我使用 TDM-GCC 编译,需要把 main() 中的 mergearr()  的函数声明删除才能编译通过,就是这一行:
  1.         int mergearr(int a[],int m,int b[],int n);
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-3-14 13:29:26 | 显示全部楼层
jackz007 发表于 2019-3-14 12:36
我重写了 mergearr() 楼主可以对照参考

      我使用 TDM-GCC 编译,需要把 main() 中的 mergearr() ...

emmmm  有两个地方不明白,第一个是为何用const,第二个是我将函数替换我原来函数之后,p和q的值依然发生了变化,一直不理解为何p,q值会变。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-14 14:13:52 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2019-3-14 14:17 编辑
路易大魔王 发表于 2019-3-14 13:29
emmmm  有两个地方不明白,第一个是为何用const,第二个是我将函数替换我原来函数之后,p和q的值依然发生 ...


    main() 函数中对 c[] 定义的时候,没有为 d[] 预留空间,导致拼接后 c[] 严重越界
  1.         int c[]={1,2,3,5,7,9};
复制代码

    所以,我对 main() 也做了修改:
  1. #include <stdio.h>

  2. mergearr(int a[] , const int m , const int b[] , const int n)
  3. {
  4.         int i = 0 , j = 0 , k                               ;
  5.         for(i = 0 ; i < n ; i ++) a[m + i] = b[i]           ;
  6.         for(i = 1 ; i < m + n ; i ++) {
  7.                 j = i                                       ;
  8.                 while(j > 0 && a[j] < a[j - 1]) {
  9.                         k = a[j]                            ;
  10.                         a[j] = a[j - 1]                     ;
  11.                         a[j - 1] = k                        ;
  12.                         j --                                ;
  13.                 }
  14.         }
  15.         for(i = 0 ; i < m + n ; i ++) printf("%d\n" , a[i]) ;
  16.         return m + n                                        ;
  17. }

  18. main(void)
  19. {
  20.         int i , j , p , q , length                           ;
  21.         int c[20] = {1 , 2 , 3 , 5 , 7 , 9}                  ;
  22.         int d[] ={2 , 4 , 5 , 6 , 8 , 9 , 10}                ;
  23.         p = 6                                                ; // 求c[]长度
  24.         q = sizeof(d) / sizeof(int)                          ;
  25.         printf("调用前 p = %d , q = %d\n" , p , q)           ; //验证函数各项数值,可忽略
  26.         length = mergearr(c , p , d , q)                     ;
  27.         printf("length = %d\n" , length)                     ;
  28.         printf("调用后 p = %d , q = %d\n" , p , q)           ; //验证函数各项数值,可忽略
  29.         for(i = 0 ; i < length ; i ++) printf("%d ," , c[i]) ;
  30. }
复制代码

        const 的意思是变量在函数内只读,不允许修改,编译程序在检查语法的时候会更加严格。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-3-14 16:40:48 | 显示全部楼层
jackz007 发表于 2019-3-14 14:13
main() 函数中对 c[] 定义的时候,没有为 d[] 预留空间,导致拼接后 c[] 严重越界

    所以,我 ...

明白了,原来我输出错误的原因是因为数组c[]的溢出,可纠结死我了,非常感谢。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-17 11:42

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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