The field-symbol is much like a pointer, but one that you can only access in a dereferenced form. In other words, it will hold, internally, the memory address of the variable that was assigned to it, but it will not allow you to see the memory address, only the data that is stored in the variable that it points to. This can be proved, because if you change the contents of a field-symbol that points to an internal table line, you'll see that the changes will be made directly in the line.
A data reference acts like a simple pointer, except that you can't increment or decrement the memory address like in C (ptr++, ptr-- and such). It differs from a field-symbol because you can compare two data references to check if they point to the exact same spot in the memory. Comparing two field-symbols will be a simple value comparison. Another difference is that you can allocate memory dynamically by creating data references, with the CREATE DATA command. A field-symbol can only be assigned to an already allocated variable.