【问题标题】:How to implement a Integer Array Adder for big integers?如何为大整数实现整数数组加法器?
【发布时间】:2015-11-16 23:26:49
【问题描述】:

由于 C 不支持大整数作为 JAVA,我正在尝试实现一个整数加法器函数,该函数将两个整数数组作为参数并返回一个指向它们总和的指针,该指针又是一个数组。这是我的代码。

#include<stdio.h>
#include<stdlib.h>
int max(int a,int b) {
    return a < b ? b : a;
}

int* decimalAdder (int* p, int* q) {
    int size1, size2, i;
    size1 = sizeof(p) / sizeof(int);
    size2 = sizeof(q) / sizeof(int);
    int m = max(size1, size2) + 1;
    int* c = (int*)malloc(m * sizeof(int));
    int carry = 0;
    for(i=0 ; i<m ; i++) {
        c[i] = 0;
        if(i < size1 && i < size2) {
            c[i] += p[i] + q[i] + carry;
            if(c[i] >= 10) {
                c[i] = c[i] % 10;
                carry = 1;
            }
            else
                carry = 0;
        }
        else if(i < size1) {
            c[i] += p[i] + carry;
            if(c[i] >= 10) {
                c[i] = c[i] % 10;
                carry = 1;
            }
            else
                carry = 0;
        }
        else if(i < size2) {
            c[i] += q[i] + carry;
            if(c[i] >= 10) {
                c[i] = c[i] % 10;
                carry = 1;
            }
            else
                carry = 0;
        }
        else
            c[i] += carry;
    }
    return c;
}

//Test program
int main() {
    int a[] = {7, 5, 3, 6};
    int b[] = {3, 5, 3};
    int* sum;
    int i;
    sum = decimalAdder(a, b);
    int size = sizeof(sum) / sizeof(int);
    for(i = size ; i >= 0 ; i--)
        printf("%d", sum[i]);
    free(sum);
    sum=NULL;
    return 0;
}

输出 10 我哪里错了?我错过了什么?

【问题讨论】:

  • sizeof(p)sizeof(q)sizeof(int *) 相同。您需要将真实的数组大小作为参数传递给decimalAdder()
  • 谢谢。著名的。但是如果不知道如何确定 p 和 q 的真实大小呢?
  • 要么将长度作为 size_t 类型的附加参数传递,要么像 C 字符串一样添加尾随空字节。
  • 即使我想将数组大小作为参数传递,仍然需要确定数组大小。怎么做?这个问题stackoverflow.com/questions/37538/… 和我一样。
  • 虽然 C 没有内置大整数,但您可以使用 libgmp 之类的库来获得类似的结果。

标签: c arrays integer add biginteger


【解决方案1】:

如 cmets 中所述,sizeof(p)sizeof(q)sizeof(int *) 相同。您需要将真实的数组大小作为参数传递给decimalAdder()

首先,更改decimalAdder() 以接收尺寸:

int *decimalAdder (int *p, size_t size1, int *q, size_t size2) {
    int i;
    int m = max(size1, size2) + 1;
    int *c = malloc(m * sizeof(int));
    /* ... */
}

您询问如何确定数组的大小以将其传递给decimalAdder()。好吧,如果您动态分配数组,那么您可能知道大小(与您之前传递给 malloc(3) 的大小相同)。

如果数组是堆栈分配的(这里就是这种情况),您可以使用您在main() 中使用的sizeof() 方法,但只能在声明数组的函数内部(因为只要您传递一个本地数组到另一个函数,它会衰减为指向第一个元素的指针,您无法再确定它的大小)。

所以在这种情况下,您可以将main() 更改为:

int main(void) {
    int a[] = {7, 5, 3, 6};
    int b[] = {3, 5, 3};
    size_t size1 = sizeof(a)/sizeof(a[0]);
    size_t size2 = sizeof(b)/sizeof(b[0]);
    int* sum;
    int i;
    sum = decimalAdder(a, size1, b, size2);    
    int size = max(size1, size2);

    for(i = size ; i >= 0 ; i--)
        printf("%d", sum[i]);

    free(sum);
    sum=NULL;

    return 0;
}

请注意,int size = sizeof(sum) / sizeof(int); 不会像您期望的那样工作:sum 不是一个真正的数组,它是一个指向int 的指针,所以sizeof(sum)sizeof(int *) 相同,不是 您分配的数组的大小。 C 不跟踪这一点,您必须自己做(而不是 Java)。

【讨论】:

  • 谢谢先生。它确实有帮助。修复了我的代码及其工作。你能告诉我一些很好的参考资料,以便深入理解 C 运算符,例如 sizeof 吗?
  • @user132458 很高兴我能帮上忙。我会推荐阅读 The C Programming Language(也称为 K&R),第 2 版。它有点过时了,但它会为你在语言细节上打下坚实的基础。另一本很棒的书是Expert C Programming - Deep C Secrets,但它更高级一些。从 K&R 开始,然后决定是否要深入研究。
  • @user132458 另外,请务必查看 The Definitive C Book Guide 并在此处列出 SO:stackoverflow.com/questions/562303/…
  • 再次非常感谢。
【解决方案2】:

但是如果 p 和 q 是未知的,如何确定它的真实大小呢?

像这样:

#include<stdio.h>

void returnLen(int length){
    printf("The length of Array is:\t%d\n",length);
}

int main(void){
    int array[] = {7, 5, 3, 6, 1, 9, 3, 6, 2, 10, 55};
    int length = sizeof array / sizeof array[0];

    returnLen(length);
    return 0;
}

输出:

数组长度为:11

【讨论】:

  • 我也做了同样的事情。 size1 = sizeof(p) / sizeof(int);
  • 不一样,因为你返回的是指针的大小而不是数组的大小
  • @user132458 您只能在声明本地数组的函数中使用sizeof 技巧。这是因为一旦将数组传递给另一个函数,它就会衰减为指向第一个元素的指针,因此您无法再确定其大小。有关详细信息,请参阅我的答案。
【解决方案3】:

因为 C 中的整数数组是一种简单类型,所以在一般情况下它不会携带有关其大小的信息。有很多方法可以解决这个问题。 Michi 的答案对于静态分配的数组是正确的,如果您始终知道您将使用多少个数组元素,那么这可能足以满足您的需求。但是,如果是这种情况,那么整个练习就没有实际意义了,因为您可以只使用宏化常量并获得相同的结果。

最终您要做的是创建一个数据结构,该结构可用于携带位数(或多位数元素)。根据此代码的使用方式,类似这样的东西可能会起作用:

struct myArray{
    int length;
    int *digits;
};

这意味着您必须管理结构的内存(分配、释放、调整大小等)。此外,您可以考虑使用 #include 和 int64_t 或 uint64_t 作为数组元素,因为您可以使用更少的单元格来表示给定的大整数。

数据结构(上图)绝不是唯一的解决方案。您也可以使用链表(尽管如果您要做的只是在节点上进行简单的算术运算,那么它的重量就相当大了)。

【讨论】:

  • 使用sizeof 确定数组大小也适用于可变长度数组,而不仅仅是静态分配的(正如您的回答所暗示的那样)。区别(此处无关)是 sizeof 如果它是 VLA 则计算其操作数。
猜你喜欢
  • 1970-01-01
  • 2015-01-19
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 2011-03-24
  • 1970-01-01
相关资源
最近更新 更多