How to change value of variable passed as argument?

Solution 1:

You're wanting to change where a char* points, therefore you're going to need to accept an argument in foo() with one more level of indirection; a char** (pointer to a char pointer).

Therefore foo() would be rewritten as:

void foo(char **foo /* changed */, int baa)
{
   if(baa) 
   {
      *foo = "ab"; /* changed */
   }
   else 
   {
      *foo = "cb"; /* changed */
   }
}

Now when calling foo(), you'll pass a pointer to x using the address-of operator (&):

foo(&x, 1);

The reason why your incorrect snippet prints baa is because you're simply assigning a new value to the local variable char *foo, which is unrelated to x. Therefore the value of x is never modified.

Solution 2:

There are multiple issues:

void foo(char *foo, int baa)
{
    if (baa) 
        foo = "ab";
    else 
        foo = "cb";
}

This code changes the local pointer, but does nothing with it. To copy strings around, you need to use strcpy() to keep the interface the same:

void foo(char *foo, int baa)
{
    if (baa) 
        strcpy(foo, "ab");
    else 
        strcpy(foo, "cb");
}

However, before doing that, you'd need to ensure that foo in the function points at modifiable memory. The calling code needs to be modified to ensure that:

char x[] = "baa";
foo(x, 1);
printf("%s\n", x);

Alternatively, you can keep x as a pointer and revise the function interface:

void foo(char **foo, int baa)
{
    if (baa) 
        *foo = "ab";
    else 
        *foo = "cb";
}

and the calling sequence:

char *x = "baa";
foo(&x, 1);
printf("%s\n", x);

Both mechanisms work, but do so in their different ways. There are different sets of issues with each. There isn't a single 'this is better than that' decision; which is better depends on circumstances outside the scope of the code fragments shown.

Solution 3:

You question is titled in a generic way. You've already got answers for your specific problem. I'm going to add couple of illustrative examples for int and double types.

#include <stdio.h>

void incrementInt(int* in, int inc)
{
   *in += inc;
}

void incrementDouble(double* in, double inc)
{
   *in += inc;
}

int main()
{
   int i = 10;
   double d = 10.2;

   printf("i: %d, d: %lf\n", i, d);

   incrementInt(&i, 20);
   incrementDouble(&d, 9.7);

   printf("i: %d, d: %lf\n", i, d);
}

Output:

i: 10, d: 10.200000
i: 30, d: 19.900000