At first glance enum and #define appear as if they are completely interchangeable. There is really no noticeable difference as far as a developer is concerned between their compiled behavior. Upon a closer examination though it can be seen that there are quite a few advantages to using an enumeration over a #define statement!
One of the differences between the two is that #define is a pre-processor directive while enum is part of the actual C language. #define statements are processed by the compiler before the first line of C code is even looked at! This causes #define to be more of a text substitution in the code which has the unfortunate affect of not generating symbols that can be used to help assist the debugging process. Another unfortunate possibility of using a #define is that somewhere else in the code another programmer could #undef and then redefine the value! This could have detrimental affects on the application.
The use of enum has a large number of advantages. The first, which was already eluded to is that the compiler can generate symbols for an enum, therefore allowing the debugger to use the symbols to assist debugging. Next, the definition of an enum can generate a type such as an int that can then be checked against other variables in the program to ensure nothing fishy is being done mathematically.
Another advantage of using enum over #define is that it is more structured and object oriented! Consider the use of a state machine where ten different states need to be defined. If a change has to be made to the state machine in the future, it is relatively trivial with an enum but for a #define it could mean having to go make and change a large number of #define statements!
Most modern day debuggers watch windows will also substitute the enum definition with the numeral value so that the developer can read the defined state rather than a number that represents the state. This helps to ease debugging and minimizes the chance of misinterpreting state of the system.
These are just a few thoughts to keep in mind the next time you are faced with the decision of using #define or biting the bullet and using an enum. I prefer the latter for the reasons listed above but I would love to hear comments for either side!