The difference is that if you pass by value only the value of i changes as y is a private variable in the function foo. However if you pass by reference both values change as the function is working with the variables i and j.
To be strict C is always pass by value, the use of the & symbol sort of simulates pass by reference as the compiler uses pointers to memory locations, but that is sort of pedantic.
Pointers should be used though because they help conserve memory space, ie. the pass by reference method only uses half the memory allocation of the pass by value for it's variables. They are also vital for the implementation of dynamic memory allocation.