printf("%d %p", *p,p); //output:- 30 0000
[..] I think there should be null assignment error.
C staandard doesn't provide any such guarantees.
Dereferencing a null pointer is undefined behaviour. So, there's no point in reasoning about why it prints 30.
Btw, you should cast the pointer argument to
void* to print it:
printf("%d %p", *p, (void*)p);