The code &((struct name *)0)->b is indeed known as the "offsetof" operation and is in fact a well-known C macro.
The idea is that if a is a structure of type A then &a.b is equal to the address of a plus the offset of b in a. Since here NULL is used instead of the address of a, the result is just the offset of b in structures of type A.
According to Wikipedia,
This works by casting a null pointer into a pointer to structure st,
and then obtaining the address of member m within said structure.
While this implementation works correctly in many compilers, it has
undefined behavior according to the C standard,2 since it involves a
dereference of a null pointer (although, one might argue that no
dereferencing takes place, because the whole expression is calculated
at compile time)
So let's look at the expression in printf step-by-step.
The expression (unsigned int) & ( (struct name *)0 )->b)) calculates offset of b in struct name as described above and casts the result to an integer. The result should be equal to sizeof(long) on most platforms.
The (char*)na in the code casts na, which is a pointer to struct name to a char pointer. This is required because sizeof(char) can be assumed to be 1 while sizeof(*na) is larger than 1. What we want to do is to use the address of *na as a raw numerical address instead of doing pointer arithmetic, so that if for example na==0x1234, then the result of ((char*)na + 4) is equal to 0x1234 + 4 = 0x1238.
The sum results in a memory address. That address is equal to the address of member variable b in the object na, and is of type char *. Knowing that, the last step is to cast the address back to int * (because the type of b is int) and then to dereference the result (once again, we know that it points to b). The final outcome is the value of b, which is then printed.