tags:

views:

239

answers:

3

In a C program, how does function call by value work, and how does call by reference work, and how do you return a value?

+9  A: 

Call by value

void foo(int c){
    c=5; //5 is assigned to a copy of c
}

Call it like this:

int c=4;
foo(c);
//c is still 4 here.

Call by reference: pass a pointer. References exist in c++

void foo(int* c){
    *c=5; //5 is assigned to  c
}

Call it like this:

int c=0;
foo(&c);
//c is 5 here.

Return value

int foo(){
    int c=4;
     return c;//A copy of C is returned
}

Return through arguments

   int foo(int* errcode){

       *errcode = OK;

        return some_calculation
   }
Tom
+3  A: 

The C language does not support call-by-reference.

What you can do is pass a pointer (which works as a reference, but is different from what C++ calls a "reference") to the data your function is interested in, which enables you to do most of the things that call-by-reference is good for.

Daniel Pryden
The C language standard says that a pointer value *"provides a reference to an entity of the referenced type"* - the C++ term "reference" is a lot more narrow than the wider CS meaning.
caf
@caf: You are quite correct, in both your statements. Additionally, "call-by-reference" is a different thing with a meaning that is more similar to C++'s references than the generic "reference" concept of the C language. Call-by-reference introduces specific semantic capabilities, foremost of which is that callees can rebind variables in the caller's context. Passing a pointer is *not* the same, since the callee can mutate the pointed-to object, but cannot rebind the caller's pointer to point to something else.
Daniel Pryden
A: 

Note that if you want to modify a pointer you must pass the pointer itself by reference.

In this example, p is changed on the stack only (in the scope of the function) and will gain its old value when the function exits:

void do_nothing(char *p)
{
    p = (char *)malloc(100);
}

To modify a pointer you must pass it by reference:

void my_string(char **p)
{
    *p = (char *)malloc(100);
}

and the call:

char *str = NULL;
my_string(&str);
...
free(str);
eyalm
This is a consequence of the fact that passing a pointer is not the same as call-by-reference. Hence, to pass a mutable pointer, you need to pass a pointer (by value) to a pointer that refers to your data. The actual argument is still always passed by value.
Daniel Pryden