Readability of course is in the eye of the beholder.
Having said that, I will agree that writing if(ptr==NULL)
is better style than if(!ptr), for at least two reasons:
(1) ! is a logical "not" operator, and it is unnatural
to apply it to a pointer value (address).
I disagree. First, I don't believe there's anything particularly
"natural" about pointers. Their correspondences with "real world"
entities are tenuous, so relying on intuitive understanding of
pointer operations is a recipie for disaster anyway. Second, the
idiom "!ptr" specifically does *not* refer to the pointer's value
as an "address", since it only distinguishes between two classes of
pointer values: null and non-null, and a null pointer is distinct
from any valid object address. Third, by the same reasoning, a
logical operation is perfectly reasonable; the pointer's value is
either null (false) or not-null (true), as the response to the
predicate "does this point somewhere?".
(2) In order to understand the code snippet, one has to
mentally map it into if(ptr is a null pointer), which is
more directly expressed as if(ptr==NULL).
Perhaps some need to read that as "ptr is a null pointer", but I've
never done so. It's just as possible to read it as "ptr doesn't
point anywhere", which is not expressed by "ptr==NULL" (though that's
an equivalent *C* expression, of course).
Readability certainly is a function of audience, in part because
interpretation is performed by the reader, which makes generaliza-
tions about how a particular idiom is read and interpreted (and hence
about how it should be expressed to best guide interpretation)
suspect. It's entirely possible that, for example, most of the
potential future maintainers of the C code that I write would
interpret the "if (!ptr)" idiom the way you do, and so I'd be better
off using "if (ptr==NULL)"; but that's an untestable hypothesis.