while ( !(UCSRA & (1<<RXC)) ) vs while (RXC == 0)
Why do we just don't write
      while (RXC == 0); 


Because "RXC" is a constant 7. Which is the number of the RXC bit in UCSRA register. So, while() will exit immediately, because it is expanded into 
while (7 == 0);

Note, that I've given you an example for ATmega32. For different controller "RCX" macro can have different value.

And just in case you are wondering, "UCSRA" and "UDR" in your code are also two macro definitions referencing another macro, _SFR_IO8.

UPDATE

For example, the macros:

#define RXC     7
#define UCSRA   _SFR_IO8(0x0B)


transform the code while (!(UCSRA &amp; (1&lt;&lt;RXC))); into

while (!(_SFR_IO8(0x0B) &amp; 0x80));


Then the macro

#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)


transforms the code further into

while (!(_MMIO_BYTE((0x0B) + __SFR_OFFSET) &amp; 0x80));


Since _MMIO_BYTE and __SFR_OFFSET are also macros, the process continues until all macro directives processed. In the end you get yourself a code that reads 
UCSRA register and applies mask for bit #7 in it.

The whole reason for all this is to make code more portable. For example by changing 0x0B in the UCSRA macro we can access UCSRA registers in different controllers without changing register address in our code.