Describe the purpose of the volatile keyword in C. When and why must it be used when interfacing with hardware registers?