Which of the following methods is a more correct way to initialize a variable?
// int x = NULL; `NULL` implies pointer
int x = 0; // 0 implies integer value and x is an integer.
What about the pointers?
void *p = NULL; // `NULL` implies pointer and p is a pointer.
//void *p = 0; // 0 implies integer value
that NULL is equal to 0
It is equal in value, though maybe not in bit pattern. See below +0.0, -0.0 example.
If NULL was equal to 0, always, then there would not be a need for it in C.
NULL is a null pointer consonant - it often, but does not always have a bit pattern of zeros. A pointer with a NULL value will always compare equally to 0: same value, different bit patterns.
Remember that == compares values, not bit patterns.
void *a = NULL;
if (a == NULL) Always_True();
if (a == 0) Always_True();
Example that may help. +0.0 and -0.0 have the same value, same type, but different bit patterns. Similar thing may happen with pointers.
int main(void) {
double pz = +0.0;
double nz = -0.0;
printf("=:%d bits:%d\n", pz == nz, memcmp(&pz, &nz, sizeof pz) == 0); // =:1 bits:0
return 0;
}