1

When I pass in an array as a parameter in a function in C, does it create a copy of the array or does it actually make changes to the original array? I have a small program here that translates a number into its binary form. For example, if the number is 15, the binary form would be 1111.

void convertToBinary(int base10, int result, char *binaryResult){
    int binaryVals[8] = {1,2,4,8,16,32,64,128};
    if(base10 == 0){ 
        printf("Binary Result %s", binaryResult);
    }   
    else{
        int max = 0;
        for(int i = 0; i < 8; i++){
            if(binaryVals[i] <= base10){
                binaryResult[i] = '0';
            }   
            else{
                max = binaryVals[i-1];
                binaryResult[i-1] = '1';
                result = base10-max;
                printf("Result %d", result);
                break;
                //convertToBinary(result,0, binaryResult);
            }   
        }   
    }   
}
int main(void){
   char binaryResult[8];
   convertToBinary(15,0,binaryResult);
}

The recursion part is failing me. I am not sure why. I suspect that it is because it is creating a copy of the array each time it runs the recursion. But I am not sure how to fix that. It would be great if someone could help, thanks

cruise_lab
  • 649
  • 8
  • 21
  • does this help? http://stackoverflow.com/a/1106977/4511978 – fr_andres Sep 24 '16 at 02:31
  • http://www.c-faq.com/aryptr/aryptrequiv.html – jamesdlin Sep 24 '16 at 02:32
  • So if I pass an array to a parameter, it is making a copy of the array, but I still don't completely understand how I can modify the original array then. I am still confused about the malloc stuff and how to apply it. – cruise_lab Sep 24 '16 at 02:39
  • 1
    @J_LIU Uh, you've apparently misunderstood both links. The array is never copied. As should be evident by your function signature, it takes the array as a *pointer* to its first element. – jamesdlin Sep 24 '16 at 02:42
  • C does not support parameters of artsy type. – Keith Thompson Sep 24 '16 at 05:13

1 Answers1

2

Arrays passed into functions always modify the original array. The function declarations:

void func( int* array);
void func( int array[]);

Are equivalent, because when you call these functions with an array argument the array decays into a pointer for both. Because you're passing a pointer, you're actually passing the array by reference, and the original array is modified.

David
  • 1,624
  • 11
  • 13
  • Nit: the array only decays into a pointer in the second case; in the first case, there's no array at all. But the main point still stands. – ravron Sep 24 '16 at 02:43
  • 3
    @ravron: Both declarations are equivalent. The process that makes the second declaration equivalent to the first is not formally referred to as "array type decay". "Array type decay" is what happens to array *objects* in *expressions*. The above is a declaration, not an expression. – AnT stands with Russia Sep 24 '16 at 02:51
  • 1
    Strictly speaking: you don't pass an array to the function, but a pointer to **its first element**. That's the reason `sizeof(array)` yields the size of a pointer to `int`. For both textual variants. Semantically they are not just equivalent, but identical. – too honest for this site Sep 24 '16 at 03:00
  • @AnT: I meant that the array decays into a pointer when a function is used as an argument to the second function. But you are both correct. – David Sep 24 '16 at 03:02
  • @Olaf: In this example - yes. However, in general case the normal rules applicable to array declarations still fully apply in the second variant. You will not be able to use incomplete element type in the second variant (OK in the first), you will not be able to specify zero or negative array size (even though it is otherwise ignored). In that regard they are not equivalent. – AnT stands with Russia Sep 24 '16 at 03:40
  • "Arrays passed into functions always modify the original array." is over-states. If the argument was `const *`, the the function does not modify the array elements. If the argument was non-`const`, the the function _may_ modify the array elements. – chux - Reinstate Monica Sep 24 '16 at 04:43
  • @AnT: Not sure what you mean. The decaying per se is not specific to this example. Of course the type of the elements depends on the declaration of the array, though. Not sure what you mean with "incomplete type. `int` is a complete type. Of course if you apss an array of arrays (aka 2D array), **both** variants require a complete type. That's what I mean: they are identical. See 6.7.6.3p7 in the C standard: _A declaration of a parameter as ''array of type'' shall be adjusted to ''qualified pointer to type' ..._'. – too honest for this site Sep 24 '16 at 05:36
  • @Olaf: I'm not talking about this specific example with `int`. What I mean is that *in general case* one can try something like this: `struct S; void foo(struct S *); void bar(struct S[]);` And discover that `foo` compiles fine, while `bar` fails to compile. So, they are not entirely identical. In the second variant some things/checks take place *before* the aforementioned adjustment. And these checks might fail. – AnT stands with Russia Sep 24 '16 at 07:24
  • @AnT: Right. But I wrote about semantics. Still both variants have the same (invalid code has no semantics at all, as constraint violations invoke UB anyway). What other checks do you mean? Remember that the Premise is an array is passed and the array argument version **is** valid. – too honest for this site Sep 24 '16 at 15:54