If you define a macro twice like that, the compiler should at least give you warning, if not an error. It is an error.
§6.10.3/2 : An identifier currently defined as an object-like macro shall not be redefined by another #define preprocessing directive unless the second definition is an object-like macro definition and the two replacement lists are identical.
You can redefine a macro by explicitly removing the previous definition:
#define a 2 /* In this part of the code, a will be replaced with 2 */ ... #undef a #define a 3 /* From here on, a will be replaced with 3 */ ...
Macro replacement happens as the file is read, using the macro definitions active at that point in the file, except inside (most) preprocessing directives.
§6.10/7: The preprocessing tokens within a preprocessing directive are not subject to macro expansion unless otherwise stated.
§6.10.3.5/1: A macro definition lasts (independent of block structure) until a corresponding #undef directive is encountered or (if none is encountered) until the end of the preprocessing translation unit.