Основное отличие от символических констант в том, что перечисления имеют другую область видимости
#include <stdio.h>
int main(void)
{
enum { A, B, C };
{
enum { A = 10 };
printf("%d\n", A);
}
printf("%d %d %d\n", A, B, C);
return 0;
}
[guest@localhost c]$ .ansi t.c -o t
[guest@localhost c]$ ./t
10
0 1 2
[guest@localhost c]$
А назначение перечислений - в быстром создании констант с осмысленными именами. Дело не в том, что они идут по порядку, а в том, что по умолчанию они различаются. То есть в пределах одного перечисления не нужно заботиться о том, чтобы там что-то чему-то не было равно.