When passing data by value, the data is copied to a local variable/object in the function. Changes to this data are not reflected in the data of the calling function. For larger objects, passing data by value can be very expensive.
When passing data by reference, a pointer to the data is copied instead. Changes to the data pointed to by the pointer are reflected in the data of the calling function. Regardless of the size of the object, passing data by reference always has the same cost.
by_ref() demonstrates the syntax used to pass data by reference using pointers. by_ref2() demonstrates the syntax used to pass data by reference using references.
Do not confuse passing by reference with passing with references. It's possible to pass by reference without passing with references, but passing with references always passes by reference.