标题:继大数相加的疑惑
只看楼主
遮天云
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:农村一小伙
等 级:贵宾
威 望:12
帖 子:1132
专家分:2671
注 册:2010-6-1
结帖率:100%
已结贴  问题点数:100 回复次数:15 
继大数相加的疑惑
程序代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int t;
char* getnum(char*p)// 输入字符串
{
    int i=0;

    p=(char*)malloc(sizeof(char));//开辟一个区间先
    while ((p[i++]=getchar())!='\n')//判断 并 输入p[i]
    {
        p=(char*)realloc(p,(i+1)*sizeof(char));//
       
    }
    p[i]='\0';  //把最后一项 变成'\0’  这个我还是不懂
    printf("验证i=%d\n",i);
    return p;
}
int* bigadd(int*num,char*p1,char*p2)//相加
{
    int n=0,i;
    int ch1_n,ch2_n;
    ch1_n=strlen(p1);//判断p1的长度   减去多分配的一个区间
    ch2_n=strlen(p2);//判断p2的长度   减去最后那个多余无值区间
    printf("ch2_n=%d\n",ch2_n);
    printf("验证ch1_n=%d\n",ch1_n);
    num=(int*)malloc(sizeof(int));
    while (ch1_n>=0||ch2_n>=0)
    {
        --ch1_n; //其实这个判断可以省略
        --ch2_n;
        if (ch1_n>=0&&ch2_n>=0) num[n]=(p1[ch1_n]-'0')+(p2[ch2_n]-'0');//如果两个都还有数没有加
        if (ch1_n<0&&ch2_n>=0)num[n]=p2[ch2_n]-'0';//如果p1已经取完数
        if(ch1_n>=0&&ch2_n<0)num[n]=p1[ch1_n]-'0'; //p2取完数
        num=(int*)realloc(num,(n+2)*sizeof(int));//只要两个不同时已经取完数 就要继续分配一个区间,那么最后有一个多余
        n++;  
    }
    for(i=0;i<n;i++)
    printf("%d\n",num[i]);
    t=n-1;    //为什么是t=n-1   不是一共分配了n+1个区间吗?
    printf("验证n=%d\nt=%d\n",n,t);
    num[t]=0;//把最后那区域赋值给0  预防上一位也要进位
    //先记下num一共多少位。
    return num;
    }
int* carry(int*num)  //进位
{  
    for (int n=0;n<=t;) //从第一位开始到第t位 一直进位  帮我看看这个n<=t 有没有错
    {
        while (num[n]>=10)//当num的值大于10时候
        {
            num[n++]-=10;//  num自减10;
            num[n]+=1;//   下一位数+1;
            continue;
        }
        n++;//判断下一位数
    }
    return num;  //返回num指针
}
void printnum(int*num)//输出num的数组
{
        t=(num[t]==0)?t-1:t;
        while(t>0)       //为什么不是t>=0 ??  num[0]q去哪了?
        {printf("%d",num[t]);
          t--;
        }
}
main()
{
    int *num;
    char*p1,*p2;
    p1=getnum(p1);
    p2=getnum(p2);
    num=bigadd(num,p1,p2);
    printnum(carry(num));
}
这是论坛里一个友人发的!想必大家都看到过了!但是问题没解决!我想了好久了还是有点不明白的地方!就是我在输入验证num中的值时(就那个红色部分那块)、num[0]的值怎么会是负数啊???还有那些注释里的问题大家给看看哈!我被这题给搞的无语了!好几天了!一点进展都没有

[ 本帖最后由 遮天云 于 2010-9-23 10:23 编辑 ]
搜索更多相关主题的帖子: 大数 相加 
2010-09-23 09:39
jack10141
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:陕西西安
等 级:小飞侠
威 望:6
帖 子:706
专家分:2271
注 册:2010-8-10
得分:10 
回复 楼主 遮天云
(就那个红色部分那块)
是哪一行?我怎么没找到呢?

Coding就像一盒巧克力,你永远不会知道你会遇到什么BUG
别跟我说你是不能的,这让我愤怒,因为这侮辱了你的智慧
2010-09-23 10:08
遮天云
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:农村一小伙
等 级:贵宾
威 望:12
帖 子:1132
专家分:2671
注 册:2010-6-1
得分:0 
for(i=0;i<n;i++)
    printf("%d\n",num[i]);
咦!怎么没变啊就这个!在相加函数里面
2010-09-23 10:22
jack10141
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:陕西西安
等 级:小飞侠
威 望:6
帖 子:706
专家分:2271
注 册:2010-8-10
得分:0 
楼主是拿别人的代码在看?为什么不去自己写一个呢?思路很简单呢!!大妈写起来也没什么技术可言呢!!

Coding就像一盒巧克力,你永远不会知道你会遇到什么BUG
别跟我说你是不能的,这让我愤怒,因为这侮辱了你的智慧
2010-09-23 10:55
遮天云
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:农村一小伙
等 级:贵宾
威 望:12
帖 子:1132
专家分:2671
注 册:2010-6-1
得分:0 
呃!谢谢您的建议!这个我道是知道!我也写过了这个程序!不过看这个程序的实现方法有值得学习的地方!多读别人的优秀代码嘛!学学经验!不过就是这个程序把我整的好郁闷啊!画了那么多图纸还是不明白!不过整体思路我是清楚了!就是有个别主贴里我说的问题还是没明白!所以想在这请各位前辈在给指教下!
2010-09-23 10:59
wcyg
Rank: 2
等 级:论坛游民
帖 子:25
专家分:31
注 册:2010-9-9
得分:5 
不错关注

[url]http://www.[/url]
2010-09-23 11:23
ppfly
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
帖 子:297
专家分:1956
注 册:2009-5-17
得分:0 
回复 楼主 遮天云
num[0]=('\n'-'0')+('\n'-'0')=(10-48)+(10-48)=-76.

********多贴代码,少说空话*******
2010-09-23 12:07
vandychan
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
等 级:贵宾
威 望:18
帖 子:2296
专家分:6418
注 册:2010-8-20
得分:5 
以下是引用遮天云在2010-9-23 10:59:01的发言:

呃!谢谢您的建议!这个我道是知道!我也写过了这个程序!不过看这个程序的实现方法有值得学习的地方!多读别人的优秀代码嘛!学学经验!不过就是这个程序把我整的好郁闷啊!画了那么多图纸还是不明白!不过整体思路我是清楚了!就是有个别主贴里我说的问题还是没明白!所以想在这请各位前辈在给指教下!
遮天的帖 就是要狂顶

到底是“出来混迟早要还”还是“杀人放火金腰带”?
2010-09-23 12:11
ppfly
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
帖 子:297
专家分:1956
注 册:2009-5-17
得分:40 
我对你的疑问写了一份注释,附在代码上,你看看是否满意~
num[0]是两个换行符与'0'的差的和,所以是一个负数。

PS:如果LZ觉得满意,不妨结贴,我对100分垂涎已久啊~~~~~~~~
程序代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int t;
char* getnum(char*p)// 输入字符串
{
    int i=0;

    p=(char*)malloc(sizeof(char));//开辟一个区间先
    while ((p[i++]=getchar())!='\n')//判断 并 输入p[i]
    {
        p=(char*)realloc(p,(i+1)*sizeof(char));//
      
    }

    //上面分配了i+1个char型空间,但是只输入了i个数字(字符),注意所有输入的字符组成一个字符数组(字符串),所以最后一个要赋值'\0'

    p[i]='\0';  //把最后一项 变成'\0'  这个我还是不懂

    //这里的验证可以看出,当我们输入一个九位数时,i值是10,所以上面要加p[i]='\0';
    printf("验证i=%d\n",i);
    return p;
}
int* bigadd(int*num,char*p1,char*p2)//相加
{
    int n=0,i;
    int ch1_n,ch2_n;
    ch1_n=strlen(p1);//判断p1的长度   减去多分配的一个区间
    ch2_n=strlen(p2);//判断p2的长度   减去最后那个多余无值区间
    printf("ch2_n=%d\n",ch2_n);
    printf("验证ch1_n=%d\n",ch1_n);
    num=(int*)malloc(sizeof(int));
    while (ch1_n>=0||ch2_n>=0)
    {
        --ch1_n; //其实这个判断可以省略
        --ch2_n;

        /*这里num[0]为什么是负数?因为num[0]=(p1[ch1_n]-'0')+(p2[ch2_n]-'0');此时ch1_n=strlen(p1)-1,ch2_n=strlen(p2)-1,
        考虑到数组下标从0开始,而且函数char* getnum(char*p)的循环条件是输入不为'\n',所以这里p1[ch1_n]=p2[ch2_n]='\n',所以
        num[0]=('\n'-'0')+('\n'-'0')=(10-48)+(10-48)=-76.
        */

        if (ch1_n>=0&&ch2_n>=0) num[n]=(p1[ch1_n]-'0')+(p2[ch2_n]-'0');//如果两个都还有数没有加
        if (ch1_n<0&&ch2_n>=0)num[n]=p2[ch2_n]-'0';//如果p1已经取完数
        if(ch1_n>=0&&ch2_n<0)num[n]=p1[ch1_n]-'0'; //p2取完数
        num=(int*)realloc(num,(n+2)*sizeof(int));//只要两个不同时已经取完数 就要继续分配一个区间,那么最后有一个多余
        n++;
    }
   
    for(i=0;i<n;i++)
        printf("%d\t",num[i]);

    //我们的确分配了n+1个区间,但是对于num[n],我们没有赋值,就是说最后一个int型空间我们没有利用
    //注意上面的while循环,注意两个循环条件:||和>=:(ch1_n>=0||ch2_n>=0),所以当ch1_n和ch2_n都变为0时,没有结束循环,而是再执行一次
    //循环体,但是这一次三个if条件都不满足,所以这一次程序虽然又分配了空间,但是没有进行任何对num数组的赋值,
    //进而上面打印num[i]时最后一个是一个随机量,因此下面t=n-1;

    t=n-1;    //为什么是t=n-1   不是一共分配了n+1个区间吗?

    printf("验证n=%d\nt=%d\n",n,t);
    num[t]=0;//把最后那区域赋值给0  预防上一位也要进位
    //先记下num一共多少位。
    return num;
    }
int* carry(int*num)  //进位
{ 
    for (int n=0;n<=t;) //从第一位开始到第t位 一直进位  帮我看看这个n<=t 有没有错
                        //这里n<=t与n<t效果一样,因为上一个函数里num[t]=0;不满足下面的循环条件
    {
        while (num[n]>=10)//当num的值大于10时候
        {
            num[n++]-=10;//  num自减10;
            num[n]+=1;//   下一位数+1;
            continue;
        }
        n++;//判断下一位数
    }
    return num;  //返回num指针
}
void printnum(int*num)//输出num的数组
{
        t=(num[t]==0)?t-1:t;

        //下面为什么是t>=0,相信你看了上面的注释已经明白了,num[0]=('\n'-'0')+('\n'-'0')=(10-48)+(10-48)=-76.
        //num[0]是两个字符串末尾换行符的和,所以我们舍弃num[0]。

        while(t>0)       //为什么不是t>=0 ??  num[0]去哪了?
        {printf("%d",num[t]);
          t--;
        }
}
int main()
{
    int *num;
    char*p1,*p2;
    p1=getnum(p1);
    p2=getnum(p2);
    num=bigadd(num,p1,p2);
    printnum(carry(num));
    return 0;
}



[ 本帖最后由 ppfly 于 2010-9-23 12:40 编辑 ]

********多贴代码,少说空话*******
2010-09-23 12:38
遮天云
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:农村一小伙
等 级:贵宾
威 望:12
帖 子:1132
专家分:2671
注 册:2010-6-1
得分:0 
以下是引用vandychan在2010-9-23 12:11:44的发言:

遮天的帖 就是要狂顶
呵呵!你一直以来都很支持我哈
2010-09-23 12:39



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-321136-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.135228 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved