ISO C defines a special way to write a null pointer: a literal `0' (or `0L', which is the same thing but sometimes used for arcane C reasons). You may convert such a literal 0 into any pointer type.
Since such a conversion is required for comparison, this means you can test if a pointer p is null by saying "p == 0" (and if it's not null by "p != 0"). For other C types, a test against 0 can be eliminated, so C defines the required conversions to let you say "! p" and "p", respectively.
Note that you should not perform any casting on this 0 value! In fact, you should just #include <stddef.h> and have done with it. There is no reason to overspecify the standard.
For convenience, the standard header <stddef.h> defines a macro NULL as `0' or `0L'. Common practice in C is to use NULL instead of `0' to represent the null pointer. However, the abbreviated tests are so convenient that they usually get used too.
NOTE: It might appear that C implementations are forced by these rules to represent a null pointer by a 0 bit-pattern. This is not true: the implementation can always distinguish pointer types from integer types, and can therefore represent the null pointer by any bit-pattern that cannot arise as a legal pointer. It then provides the appropriate conversions.
In particular, the following code:
{
char **p = calloc(1000, sizeof(char *));
/* ... */
}
does NOT allocate an array of 1000 null pointers!
These distinctions lead one to the allied conclusion that null is not zero.
C++ has generally abolished the use of the NULL macro, preferring instead the unadorned constant `0'. However, since the header file <cstddef> is still available, you can use it. That does not mean you should. Instead, write in the style of your chosen language!