Count me as a developer that knew there was a difference between control-c and control-z, but couldn't tell you the details of the difference. If I have a non-responsive process, I generally try control-c first. But if that doesn't work, I resort to using control-z, followed by the kill command to end the process by id.
So I looked it up:
Control-C kills a process with a SIGINT signal from the operating system. The process has the opportunity to handle this interrupt and terminate gracefully.
Control-Z suspends a process with a SIGSTOP signal from the operating system. The process does not have the opportunity to handle the interrupt and will be suspended. This is why control-z works in cases when control-c fails. The suspended process can then be resumed, either in the foreground or background, or can be killed all together.
Note: this is for Unix based systems.