NULL in C programming can anyone tell me how NULL is handled in C? And the output of this program is 3, how with NULL concept?
#include <stdio.h>
int main(void) {开发者_StackOverflow
int i;
static int count;
for(i = NULL; i <= 5;) {
count++;
i += 2;
}
printf("%d\n",count);
return 0;
}
For C, "NULL" is traditionally defined to be (void *)0 - in other words, it's a pointer alias to address 0. For C++, "NULL" is typically defined to be "0". The problem with NULL in C++ and C is that it's not type safe - you can build bizarre constructs like the one you included in your code sample.
For C++, the language designers fixed this in C++0x by adding a new "nullptr" type which is implicitly convertable to any pointer type but which cannot be converted to an integer type.
NULL
is just a macro defined in stdio.h
or a file that stdio includes. It can variously be defined as some variation of zero.
If you run your code through the C pre-processor (usually cc -E
) you can see what it translates to on your implemnentation:
void main(){
int i;
static int count;
for(i=((void *)0); i<=5 ;){
count++;
i+=2;
}
printf("%d",count);
}
which is not only an unnecessary use of NULL
but is wildly un-idiomatic C code, more ordinary would be:
int main(){
int i;
int count = 0;
for(i = 0; i <= 5; i += 2){
count++;
}
printf("%d\n",count);
return 0;
}
There's a whole chapter devoted to the Null pointer in the C FAQ that should answer all your questions.
- 5.1 What is this infamous null pointer, anyway?
- 5.2 How do I get a null pointer in my programs?
- 5.3 Is the abbreviated pointer comparison
if(p)
to test for non-null pointers valid? What if the internal representation for null pointers is nonzero? - 5.4 What is
NULL
and how is it defined? - 5.5 How should NULL be defined on a machine which uses a nonzero bit pattern as the internal representation of a null pointer?
- 5.6 If
NULL
were defined as follows:#define NULL ((char *)0)
. Wouldn't that make function calls which pass an uncast NULL work? - 5.7 My vendor provides header files that #define NULL as 0L. Why?
- 5.8 Is
NULL
valid for pointers to functions? - 5.9 If
NULL
and 0 are equivalent as null pointer constants, which should I use? - 5.10 But wouldn't it be better to use
NULL
(rather than 0), in case the value ofNULL
changes, perhaps on a machine with nonzero internal null pointers? - 5.11 I once used a compiler that wouldn't work unless
NULL
was used. - 5.12 I use the preprocessor macro
#define Nullptr(type) (type *)0
to help me build null pointers of the correct type. - 5.13 This is strange.
NULL
is guaranteed to be 0, but the null pointer is not? - 5.14 Why is there so much confusion surrounding null pointers? Why do these questions come up so often?
- 5.15 I'm confused. I just can't understand all this null pointer stuff.
- 5.16 Given all the confusion surrounding null pointers, wouldn't it be easier simply to require them to be represented internally by zeroes?
- 5.17 Seriously, have any actual machines really used nonzero null pointers, or different representations for pointers to different types?
- 5.18 Is a run-time integral value of 0, cast to a pointer, guaranteed to be a null pointer?
- 5.19 How can I access an interrupt vector located at the machine's location 0? If I set a pointer to 0, the compiler might translate it to some nonzero internal null pointer value.
- 5.20 What does a run-time ``null pointer assignment'' error mean? How can I track it down?
NULL
has most of its meaning when dealing with pointers. When dealing with integers, you would be better off using simply zero.
Strictly speaking, NULL
is simply the value zero with a fancy name, but the most important part about it is indeed its fancy name. It exists because it's less ambiguous to write int* p = NULL;
than int* p = 0;
. Since we know NULL
is a pointer, we're sure that I really meant p
to be a pointer.
So, when you deal with pointers and want to represent the address 0
, use NULL
. And when you deal with numbers and want to represent the number 0
, use 0
. (In your example, you should use 0
instead of NULL
.)
NULL
is should be synonymous with 0
. It's more correctly used to indicate a null pointer.
In this case the code will actually be:
for (i = 0; i <= 5)
{
count++;
i += 2;
}
NULL is defined as 0 by C. In your program, it counts from 0 to 5 (counting every 2nd number). That's why count is 3 (i = 0, 2, 4).
NULL shouldn't be used this way. NULL should be used with pointers.
The type of NULL
and the type of i
are different, but C
forgives you :)
C
is (mostly) not a "type-safe" language. I mean: it lets you mix types which other languages would complain.
With C
you can add chars
to doubles
, you can multiply chars
and ints
, ...
What you are doing is assigning a null pointer constant
(of type void *
) to an int
. C
allows that, but you need to be very careful when mixing types like this.
The result of assigning the null pointer constant to an int is the same as assigning 0
to it. So you start your loop with i
being 0
.
A static auto variable, in the absence of an initializer, is initialized to 0
. This happens to the variable count
in your program.
So, the loop goes first (count
becomes 1) with i
being 0, then i
becomes 2.
Now the loop goes (count
becomes 2) with i
being 2, then i
becomes 4.
Now the loop goes (count
becomes 3) with i
being 4, then i
becomes 6.
And the loop terminates ... and you print the value of count
.
Notes
- to be Standard compliant
main
should be declaredint main(void)
- you should output a newline after every complete line (
printf("%d\n", count);
) - and you should
return 0;
to indicate successful completion of your program to the Operating System
Don't confuse the idea of a NULL pointer in c with that of a nullable type or quantities in some dynamic languages. There are similar, but have distinct uses and meaning.
In c the concept of NULL is only used natively in the context of pointer where it is a pointer to a known invalid memory location (often, but not always, represented by zero).
This is not (quite) the same as a type or variable which can represent non-setness. Note that types like this can be defined-and-managed by the user in c, but they are not supplied by the language.
精彩评论