In Java, all primitive types are passed to functions by value — the function is unable to change values of variables in the invoking context. All class types are passed by reference — the function can alter the public contents of the referenced object.

In C, almost all types are passed by value, and so no variables supplied as arguments can be altered by a function. It can only alter its local copies of the variables. However, by passing a pointer to the variable, the function is able to dereference its copy of the pointer, and indirectly assign to the variable. Consider these two functions which are intended to swap the values of two variables:

void badswap(int a, int b)
{
  int tmp = b;
  b = a;
  a = tmp;
  /* a and b are swapped but they're only copies. */
}

void goodswap(int *ap, int *bp)
{
  int tmp = *bp;
  *bp = *ap;
  *ap = tmp;
}

/* Assume we're in a function body. */
int x = 10, y = 4;

/* Print state of variables. */
printf("1: x = %d y = %d\n", x, y);

badswap(x, y);
/* x and y are copied, and the copies are swapped
   so x and y are unchanged. */

printf("2: x = %d y = %d\n", x, y);

goodswap(&x, &y);
/* Pointers tell goodswap() where we store x and y. */

printf("3: x = %d y = %d\n", x, y);

This reports:

1: x = 10 y = 4
2: x = 10 y = 4
3: x = 4 y = 10

…indicating that badswap had no effect on the variables given as arguments.