Unions are used for reducing storage costs, accessing data with different internal representations, and creating a poor man's polymorphism.

Reducing storage costs entails exactly what you would think. Instead of using separate memory blocks for objects that will not exist simultaneously, you place them in a union and only use one at a time to save space. Accessing data with different internal representations was already described previously by FillYourBrain, so I won't go into further detail unless you want me to. The poor man's polymorphism is fairly simple. You use a structure with two members: a type identifier and a union of the different types. The union shares storage among different objects and the type identifier tells which object is in use at the time. This also saves space, but the intention is a heterogeneous data type rather than space efficiency.