A hardware interrupt takes place on a hardware level. These can be things like traps and halts, where the processor itself saves its state and waits for input or executes something else that was not necessarily part of the original program (i.e. if you divide by zero, your processor has to do something that it was not intending to do during the normal execution of the program).
Perhaps more importantly, a hardware interrupt allows a processor not to waste time in what are called polling loops. Imagine if you had to see if the user was pressing a key. There are two ways of doing that. The first is by checking very often and seeing if the key is pressed. While this will work, it is wasteful, as the vast majority of the time the check comes back negative. Interrupts allows the key press itself to change the state of the program so that it gets "notified" when a key is pressed. The second way is clearly more efficient in many cases.
A software interrupt usually means a context switch, and it done by the operating system. In some cases it means nothing more than the OS swapping which program is executing at the moment (if your computer is running 50 processes, unless you have 50 cores/threads the fact that programs simultaneous program execution is an illusion) so something similiar to the above example with the keyboard, where it is waiting for some event to occur (see more about event based programming here (from Wikipedia))
It is important to note that while in many cases interrupt based programming is a good idea, in application where there are many interrupt based programming is a good idea, if it occurs too frequently, it may be less efficient, and perhaps even crash the system.