There's not much more to say about extern than what shabbir's already posted, in fact I think it's fair to say he's nailed it. extern is an indicator to the compiler that the variable definition that follows exists in another file so it shouldn't allocate space for it. That's all.

As for enums, see
It doesn't make sense to want to use enums of 1 byte; this suggests you don't know what they're for. enum is an integer-like type that enumerate a list of related constants and you first define the enum with a name, e.g. enum X { A,B,C};, then you define a variable of type enum X and you can set it to A,B or C. The compiler handles the type, so it would be inadvisable to assume anything about the size taken up by such a variable; instead use a switch for example:
enum X { A,B,C };
enum X foo;
int bar;
switch (x)
case A: bar=1; break;
case B: bar=2; break;
case C: bar=3; break;
Because if you just do something like int quux=(int)foo, which should compile OK, and someone comes along later and changes the enum to enum X { A=1,B=10,C };, which is valid, but now quux has completely different values, whereas with the switch above, regardless of the actual values of A,B and C, bar predictably contains 1,2 or 3.

Also I would suggest that int quux=(int)foo is an *optimisation* and should not be done until code profiling has shown that the above switch statement is a bottleneck (which it will almost certainly never be).