Reverse Engineering (RE) is the decompilation of an application, regardless of the programming language that was used to create it, so that one can obtain its source code or any part of it.
The reverse engineer can reuse the obtained code in his own programs or change an existing (already compiled) program to perform in other ways. He can use the knowledge obtained from reverse engineering to improve application programs, also known as bugs. But the most important is that one can get extremely useful ideas by observing how other programmers work and think, thus improve his skills and knowledge!
What comes in our minds when we hear RE, is cracking. Cracking is as old as the programs themselves. To crack a program, means to trace and use a serial number or any other kind of registration data, needed for the proper operation of a program. Therefore, if a shareware program (freely distributed, but with some difficulties, like crippled functions, nag screens or limited capabilities) needs a valid registration data, a reverse engineer can give that information by decompiling a particular part of the program.
In the past, many software companies have blamed others for doing RE in their products and stealing technology and knowledge. Reverse engineering is not limited to computer applications, the same happens with a car, weapons, hi-fi elements etc.