利用一位加法器实现大数相加

来源:互联网 发布:中经云数据存储 编辑:程序博客网 时间:2024/06/03 03:32
#include<stdio.h>#include<stdlib.h>/*编写十进制一位加法器add()以被加位、加位、低位进位为参数,用十进制数字字符表示,以本位结果和高位进位为输出。实现两个任意长整数加法,其他过程自理,不能使用字符串库函数。*///字符数组初始大小101,如果不够,动态增加,每次加20#define MAX 101#define INCREARMENT 20typedef struct ADDITEM{char baseBit;//本位char carryBit;//进位}ADDITEM;//十进制一位加法器//以被加位、加位、低位进位为参数,//用十进制数字字符表示,以本位结果和高位进位为输出ADDITEM Add(char num1,char num2,char carryBit){ADDITEM item;int num;num = num1 + num2 + carryBit - '0'*3;item.baseBit = num % 10 + '0';item.carryBit = num / 10 + '0';return item;}//输入"无限大小"整数,以Enter结束char* inputStr(char* str){//str_len字符串的长度,max_size当前字符数组空间大小int str_len , max_size;char ch;str_len = 0;max_size = MAX;str = (char*)malloc(sizeof(char) * max_size);if (str == NULL){printf("allocation failture\n");}scanf("%c",&ch);while(ch!='\n'){str[str_len] = ch;str_len = str_len + 1;//空间不足,追加空间,每次加INCREAMENT个if(str_len >= max_size){str = (char*)realloc(str,sizeof(char)*(max_size + INCREARMENT));if (!str){printf("allocation failture\n");}max_size = max_size + INCREARMENT;}scanf("%c",&ch);}str[str_len] = '\0';return str;}//get the length of strint StrLen(char* str){int len;len = 0;while(str[len] != '\0'){len = len + 1;}return len;}//将字符串反转void strReverse(char* str){int i,len;char ch;len = StrLen(str);for (i = 0;i<len/2;i++){ch = str[i];str[i] = str[len - i - 1];str[len - i - 1] = ch;}}int GetMax(int a,int b){return a>b?a:b;}//逆序相加char* BigNumAdd(char* num1,char* num2){int len1,len2,len3,i1,i2,i3;char* str;//存储结果ADDITEM item;len1 = StrLen(num1);len2 = StrLen(num2);len3 = GetMax(len1,len2);//两数相加,结果肯定不会大于两者最大值+2,str = (char*)malloc(sizeof(char)*(len3+2));//一个字符保存'\0',另一个保存进位item.carryBit = '0';i1 = 0; i2 = 0;i3 = 0;strReverse(num1);//将字符串反转strReverse(num2);while(num1[i1]!='\0' && num2[i2]!='\0'){item = Add(num1[i1],num2[i2],item.carryBit);//调用一位加法器str[i3] = item.baseBit;i3  = i3 + 1;i1 = i1 + 1;i2 = i2 + 1;}while(num1[i1]!='\0'){item = Add(num1[i1],'0',item.carryBit);str[i3] = item.baseBit;i3  = i3 + 1;i1 = i1 + 1;}while(num2[i2]!='\0'){item = Add('0',num2[i2],item.carryBit);str[i3] = item.baseBit;i3  = i3 + 1;i2 = i2 + 1;}if (item.carryBit > '0')//判断最后是否有进位{str[i3] = item.carryBit;i3  = i3 + 1;}str[i3] = '\0';strReverse(str);//将结果翻转return str;}int main(int argc,char* argv[]){char *num1,*num2,*num3;num1 = inputStr(num1);num2 = inputStr(num2);num3 = BigNumAdd(num1,num2);//num1,num2的数据被反转,因为BigNumAdd中使用逆序求和,没有将num1,num2恢复为初始数据printf("%s\n",num1);printf("%s\n",num2);printf("%s\n",num3);return 0;}/*如何在子函数使用malloc 和 relloc 给数组开辟空间然后在主函数或者其他地方使用错误方法:void f(char* str){str = (char*)malloc(sizeof(char)*100);}原因,malloc()分配的内存并没用释放,只有free之后才会释放。为什么又会出错呢?传递的str是表示一个指向字符数组的指针,即该传递方法为值传,是一个局部变量,即主函数中str和f函数中的str是不一样的,只是数据copy,是单向传递当函数返回之后,没有像[正确方法1]那样将地址返回,因而,在主函数中引用时,str依然为空。地址传递的方法是f(char& str),传递一个字符的地址,正确方法1char* f(char* str){str = (char*)malloc(sizeof(char)*100);return str;}分析:通过指针返回开辟的空间,之后通过返回的指针,获得数据该函数退出(局部变量p所在内存已经释放)并返回到调用点str=GetMemory(...);把寄存器中的值赋值给str,就是用malloc非配的内存区基址。正确方法2void f(char** str){*str = (char*)malloc(sizeof(char*)*100);}分析:在子函数形参中使用指向指针的指针使用方法:char *str=NULL;f(&str);*/

原创粉丝点击