Can someone explain how while(foo)
vs while(foo != NULL)
are equivalent? Also:
while(!foo)
vs while(foo == NULL)
I know that ! is not, but that is about all I know.
Can someone explain how while(foo)
vs while(foo != NULL)
are equivalent? Also:
while(!foo)
vs while(foo == NULL)
I know that ! is not, but that is about all I know.
Assuming foo
is of pointer type, while (foo)
and while (foo != NULL)
are exactly equivalent. Both are also equivalent to while (foo != 0)
. (In my opinion while (foo != NULL)
more clearly expresses the intent.)
In any context requiring a condition (if()
, while()
, a few others), the expression is treated as true if the condition compares unequal to zero, false if it compares equal to zero.
NULL
is a macro that expands to an implementation-defined null pointer constant. Comparing a pointer value to NULL
yields a true value for a null pointer, a false value for any non-null pointer.
The constant 0
is a null pointer constant [*]. (This doesn't mean that a null pointer has the same bit representation of 0x00000000
or something similar, though it often does; it means that a constant 0
in source code can denote a null pointer.) As you'd expect, comparing a pointer value to a null pointer constant tells you whether that pointer is a null pointer or not. In while (foo)
, the comparison to zero is implicit -- but it still tests whether foo
is a null pointer or not.
More generally, while (foo)
compares foo
to 0
, which is equivalent to comparing it to "zero" of the appropriate type. while (foo)
is always equivalent to while (foo != 0)
. For a floating-point value, it's also equivalent to while (foo != 0.0)
. For a character value, it's equivalent to while (foo != '\0')
. And, as we've seen, for a pointer value, it's equivalent to while (foo != NULL)
.
(In C, a comparison operator always yields an int
value of 0
if the condition is false, 1
if it's true -- but any non-zero value is treated as true, via the implicit inequality comparison to zero.)
[*] A null pointer constant is defined as an integer constant expression with the value 0
, or such an expression cast to void*
. A null pointer constant isn't necessarily of pointer type, but converting it to pointer type yields a null pointer value. Comparing a pointer value to 0
causes the 0
to be implicitly converted to the pointer type so the comparison can be done.
while(foo);
and
while(foo != NULL)
Are equivalent simply because NULL is a macro that expands to either 0
, or (void*)0
or 0L
, given that in C 0 evaluates to false(and any non-zero number to true) then
while(foo); //while foo isn't 0
while(foo != NULL) //expands to while(foo != 0) < while foo isn't 0
while (expression
) repeats the enclosing block as long as expression
evaluates to any non-zero value. When expression
evalutes to 0, the while loop ends.
An expression
that's a pointer type is considered to be non-0 if the pointer value is not std::nullptr
, or NULL
.
The !
operator is a boolean not
operator.
Therefore
while (foo)
And
while (foo != NULL)
are logically equivalent to each other. Therefore, the logical inverse of the two are also equivalent to each other.
NULL
is a symbolic constant, you can think of it as a sort of replacement text. NULL
is just something that the compiler later replaces with a zero, so writing while (foo != NULL)
is the same as writing while (foo != 0)
. Remember, ==
says yes if what's to the left of it is equal to what's to the right of it, whereas !=
says yes if what's to the left of it is NOT equal to what's to the right of it.
In C, the number 0 always means false and every other number means true. So while (foo != 0)
is the same as saying "Run the code in this loop while foo is true". while (1)
, for example, is the same as saying "Run the code in this loop forever", because 1 is a number that is always different from zero and hence is always true.
In C, if you use just foo
where a true-or-false kind of value is expected, it's the same as saying foo != 0
, that's kind of like a shortcut you can use, it's the same as asking "is foo true?". !
means "not", so asking !foo
is the same as asking "is foo NOT true?", in other words "is foo false?". This means that while (!foo)
is the same as "Run the code in this loop while foo is false", which is the same as while (foo == 0)
since zero means false, which is the same as while (foo == NULL)
since NULL
means zero.
Think of it like this: the code in a loop will only run if what's in the parenthesis is true (that is, non-zero). So in while (foo)
the computer will ask "is foo non-zero?", if yes the loop keeps going. Now, if you have while (!foo)
, the computer will ask "is foo NOT non-zero?", if yes the loop keeps going. The loop only stops when the expression in the parenthesis results in false.
NULL
is defined in several standard header files, it's not a keyword like if
and while
, you need to include a header file that defines it to be able to use it. The idea is that when a pointer points to address zero, it's called a "null pointer", that's why it's called NULL
, it's used when you want to say "zero the address" rather than merely "zero the number".
Edit:
As correctly pointed out by Matt McNabb, NULL
may be defined as 0
or as (void *)0
. To stay clear of any doubt, I quote the C11 standard:
An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.
And later on
The macro NULL is defined in <stddef.h> (and other headers) as a null pointer constant; see 7.19.
Then, in Section 7.19:
3 The macros are
NULL
which expands to an implementation-defined null pointer constant; and
offsetof(type, member-designator)
which expands to...
And the text goes on. So (void *)0
and 0
are valid implementation-defined null pointer constants.
a while loop can run like so:
while(1) //This will run forever.
while(true) //This will run forever.
NULL
is like 0, so if you have while(foo != NULL)
, this is saying that while(foo is not equal to 0, so while it is equal to 1 or something else) run it.