3

Since C doesn't support Big Integers as JAVA, I am trying to implement a integer adder function which takes two integer arrays as parameter and returns a pointer to their sum which is again an array. Here is my code.

#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;
}

It Outputs 10 Where I'm going wrong? What am I missing?

ashwani
  • 690
  • 3
  • 16
  • 2
    `sizeof(p)` and `sizeof(q)` are the same as `sizeof(int *)`. You need to pass the true array sizes as arguments to `decimalAdder()`. – Filipe Gonçalves Aug 23 '15 at 13:18
  • Thanks. Noted. But how to determine the true sizes of p and q if it is unknown? – ashwani Aug 23 '15 at 13:21
  • Either pass the lengths as additional arguments of type `size_t` or add a trailing null byte like with C strings. – cadaniluk Aug 23 '15 at 13:23
  • Even if I want to pass the array sizes as parameters, the array sizes are still needed to be determined. how to do that? This question http://stackoverflow.com/questions/37538/how-do-i-determine-the-size-of-my-array-in-c does the same I did. – ashwani Aug 23 '15 at 13:35
  • While C does not have big integers built in, you can use a library like the libgmp to get a similar result. – fuz Aug 23 '15 at 13:35
  • You've got it all wrong with `sizeof`. – barak manos Aug 23 '15 at 13:51
  • [You don't cast the result of malloc in C](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – phuclv Aug 23 '15 at 14:21

3 Answers3

2

As noted in the comments, sizeof(p) and sizeof(q) are the same as sizeof(int *). You need to pass the true array sizes as arguments to decimalAdder().

So first, change decimalAdder() to receive the sizes:

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));
    /* ... */
}

You ask how to determine the size of the arrays to pass it to decimalAdder(). Well, if you dynamically allocated the arrays, then you probably know the size (it's the same you passed to malloc(3) before).

If the arrays are stack allocated (which is the case here), you can use the sizeof() method that you use in main(), but only inside the function that declares the arrays (because as soon as you pass a local array to another function, it decays into a pointer to the first element and you can no longer determine its size).

So in this case you could change main() to:

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;
}

Note that int size = sizeof(sum) / sizeof(int); won't work the way you expect: sum is not a true array, it's a pointer to int, so sizeof(sum) is the same as sizeof(int *), not the size of the array you allocated. C doesn't keep track of that, you have to do it yourself (as opposed to Java).

Filipe Gonçalves
  • 20,783
  • 6
  • 53
  • 70
  • Thanks Sir. It really did help. Fixed my code and its working. Can u tell me some good references for in-depth understanding of C operators such as **sizeof** ? – ashwani Aug 23 '15 at 14:05
  • 1
    @user132458 Glad I could help. I would recommend reading *The C Programming Language* (also known as *K&R*), 2nd edition. It's a bit dated, but it will give you a strong foundation on the language details. Another great book is *Expert C Programming - Deep C Secrets*, but it's a little more advanced. Start with *K&R* and then decide whether or not you'd like to dive deeper. – Filipe Gonçalves Aug 23 '15 at 14:49
  • @user132458 Also, make sure to check out The Definitive C Book Guide and List here in SO: http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list – Filipe Gonçalves Aug 23 '15 at 14:49
  • Thanks very much again. – ashwani Aug 23 '15 at 17:16
1

But how to determine the true sizes of p and q if it is unknown?

Like this:

#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;
}

Output:

The length of Array is: 11

fuz
  • 88,405
  • 25
  • 200
  • 352
Michi
  • 5,175
  • 7
  • 33
  • 58
  • i did the same thing. size1 = sizeof(p) / sizeof(int); – ashwani Aug 23 '15 at 13:45
  • It is not the same, because you returned the size of the pointer not the Array size – Michi Aug 23 '15 at 13:52
  • 1
    @user132458 You can only use the `sizeof` trick inside the function that declared the local array. This is because once an array is passed to another function, it decays into a pointer to the first element, so you can no longer determine its size. See my answer for more details. – Filipe Gonçalves Aug 23 '15 at 13:53
0

Because an integer array in C is a simple type, it doesn't carry along with it information about its size in the general case. There are any number of ways to address the problem. Michi's answer is correct for statically allocated arrays and perhaps that will be sufficient for your needs if you always know how many array elements with which you will be working. But, if that's the case then this whole exercise is moot since you could just use macro-ized constants and achieve the same result.

Ultimately what you will end up doing is creating a data structure that can be used to carry along the number of digits (or multi-digit elements). Depending on how this code will be used, something like this might work :

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

That means you'll have to manage the memory (allocate, free, resize, etc.) for the structure. In addition, you might consider using #include and int64_t or uint64_t as your array elements since you'll be able to use fewer cells to represent a given big int.

The data structure (above) is by no means the only solution. You could use a linked list as well (although that's fairly heavy-weight if all you are going to do is simple arithmetic on the nodes).

P. Hinker
  • 299
  • 2
  • 7
  • Using `sizeof` to determine an array size works for variable-length arrays as well, not just statically allocated (as your answer suggests). The difference (irrelevant here) is that `sizeof` evaluates its operand if it is a VLA. – Filipe Gonçalves Aug 23 '15 at 13:55