A sentinel value is an "impossible" value deliberately positioned in a data structure to denote some condition. The null pointer is probably the best-known sentinel value. It is illegal to dereference it (hence it's an "impossible" address). In a linked list, the null pointer denotes the end of the list.

When array indices are stored, -1 is the customary sentinel value. ISO C also uses the int -1 as EOF, the end of file marker. Again, -1 is an impossible value for a char (at least when sizeof(int)>sizeof(char)), so it is a safe choice.

Sentinel values are never really necessary: they're an "in band" signalling mechanism. An "out of band" mechanism could be used instead: use a separate extra bit of information which, when set, denotes the condition. The main advantage of the use of sentinel values is that they make more efficient use (often not just in terms of program time and space!) of resources. Their disadvantage is that they introduce some "magic" into the data. And woe betide who uses the data without understanding the magic!