Note: This answer applies to the C language, not C++.
Null Pointers
The integer constant literal 0 has different meanings depending upon the context in which it's used. In all cases, it is still an integer constant with the value 0, it is just described in different ways.
If a pointer is being compared to the constant literal 0, then this is a check to see if the pointer is a null pointer. This 0 is then referred to as a null pointer constant. The C standard defines that 0 cast to the type void * is both a null pointer and a null pointer constant.
Additionally, to help readability, the macro NULL is provided in the header file stddef.h. Depending upon your compiler it might be possible to #undef NULL and redefine it to something wacky.
Therefore, here are some valid ways to check for a null pointer:
if (pointer == NULL)
NULL is defined to compare equal to a null pointer. It is implementation defined what the actual definition of NULL is, as long as it is a valid null pointer constant.
if (pointer == 0)
0 is another representation of the null pointer constant.
if (!pointer)
This if statement implicitly checks "is not 0", so we reverse that to mean "is 0".
The following are INVALID ways to check for a null pointer:
int mynull = 0;
<some code>
if (pointer == mynull)
To the compiler this is not a check for a null pointer, but an equality check on two variables. This might work if mynull never changes in the code and the compiler optimizations constant fold the 0 into the if statement, but this is not guaranteed and the compiler has to produce at least one diagnostic message (warning or error) according to the C Standard.
Note that the value of a null pointer in the C language does not matter on the underlying architecture. If the underlying architecture has a null pointer value defined as address 0xDEADBEEF, then it is up to the compiler to sort this mess out.
As such, even on this funny architecture, the following ways are still valid ways to check for a null pointer:
if (!pointer)
if (pointer == NULL)
if (pointer == 0)
The following are INVALID ways to check for a null pointer:
#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)
as these are seen by a compiler as normal comparisons.
Null Characters
'\0' is defined to be a null character - that is a character with all bits set to zero. '\0' is (like all character literals) an integer constant, in this case with the value zero. So '\0' is completely equivalent to an unadorned 0 integer constant - the only difference is in the intent that it conveys to a human reader ("I'm using this as a null character.").
'\0' has nothing to do with pointers. However, you may see something similar to this code:
if (!*char_pointer)
checks if the char pointer is pointing at a null character.
if (*char_pointer)
checks if the char pointer is pointing at a non-null character.
Don't get these confused with null pointers. Just because the bit representation is the same, and this allows for some convenient cross over cases, they are not really the same thing.
References
See Question 5.3 of the comp.lang.c FAQ for more. See this pdf for the C standard. Check out sections 6.3.2.3 Pointers, paragraph 3.
Note: This answer applies to the C language, not C++.
Null Pointers
The integer constant literal 0 has different meanings depending upon the context in which it's used. In all cases, it is still an integer constant with the value 0, it is just described in different ways.
If a pointer is being compared to the constant literal 0, then this is a check to see if the pointer is a null pointer. This 0 is then referred to as a null pointer constant. The C standard defines that 0 cast to the type void * is both a null pointer and a null pointer constant.
Additionally, to help readability, the macro NULL is provided in the header file stddef.h. Depending upon your compiler it might be possible to #undef NULL and redefine it to something wacky.
Therefore, here are some valid ways to check for a null pointer:
if (pointer == NULL)
NULL is defined to compare equal to a null pointer. It is implementation defined what the actual definition of NULL is, as long as it is a valid null pointer constant.
if (pointer == 0)
0 is another representation of the null pointer constant.
if (!pointer)
This if statement implicitly checks "is not 0", so we reverse that to mean "is 0".
The following are INVALID ways to check for a null pointer:
int mynull = 0;
<some code>
if (pointer == mynull)
To the compiler this is not a check for a null pointer, but an equality check on two variables. This might work if mynull never changes in the code and the compiler optimizations constant fold the 0 into the if statement, but this is not guaranteed and the compiler has to produce at least one diagnostic message (warning or error) according to the C Standard.
Note that the value of a null pointer in the C language does not matter on the underlying architecture. If the underlying architecture has a null pointer value defined as address 0xDEADBEEF, then it is up to the compiler to sort this mess out.
As such, even on this funny architecture, the following ways are still valid ways to check for a null pointer:
if (!pointer)
if (pointer == NULL)
if (pointer == 0)
The following are INVALID ways to check for a null pointer:
#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)
as these are seen by a compiler as normal comparisons.
Null Characters
'\0' is defined to be a null character - that is a character with all bits set to zero. '\0' is (like all character literals) an integer constant, in this case with the value zero. So '\0' is completely equivalent to an unadorned 0 integer constant - the only difference is in the intent that it conveys to a human reader ("I'm using this as a null character.").
'\0' has nothing to do with pointers. However, you may see something similar to this code:
if (!*char_pointer)
checks if the char pointer is pointing at a null character.
if (*char_pointer)
checks if the char pointer is pointing at a non-null character.
Don't get these confused with null pointers. Just because the bit representation is the same, and this allows for some convenient cross over cases, they are not really the same thing.
References
See Question 5.3 of the comp.lang.c FAQ for more. See this pdf for the C standard. Check out sections 6.3.2.3 Pointers, paragraph 3.
It appears that a number of people misunderstand what the differences between NULL, '\0' and 0 are. So, to explain, and in attempt to avoid repeating things said earlier:
A constant expression of type int with the value 0, or an expression of this type, cast to type void * is a null pointer constant, which if converted to a pointer becomes a null pointer. It is guaranteed by the standard to compare unequal to any pointer to any object or function.
NULL is a macro, defined in as a null pointer constant.
\0 is a construction used to represent the null character, used to terminate a string.
A null character is a byte which has all its bits set to 0.
0 being an int like other integers, sizeof(0) will yield 4 bytes.
sizeof(NULL) will yield 8 bytes. In binary system, it is 8x8=64 bits, all bits with 0.
Pointers have 8 bytes allocated against characters with 1 bytes and integers 4 bytes. Is 8 bytes the maximum bytes for any datatype? I believe so as NULL is set to 8 bytes apparently for that reason to take care NULL denotes 0 for all datatypes.
I know that NULL is guaranteed to point to nothing, and cause a segfault when accessed, but is NULL guaranteed to be 0 on all hardware? What about false?
#include <stddef.h>
int main() {
if (!NULL) {
printf("%d\n", NULL == 0); /* Is this line always run, and is the value printed always 1? */
}
return 0;
}In C, NULL is a macro that expands either to 0 or (void*)0 (or something that has a similar effect).
In the first case, you can not differentiate between NULL and 0, because they are literally the same.
In the second case, your code will cause a compile error, because you can't compare an integer variable with a pointer.
First some background ...
The macros are
NULLwhich expands to an implementation-defined null pointer constant; C11 §7.19 3
NULL typically is an integer constant 0 or (void*)0 or the like. It may have a different implementation or type - It could be ((int*) 0xDEADBEEF) as strange as that may be.
NULL might be type int. It might be type void * or something else. The type of NULL is not defined.
When the null pointer constant NULL is cast to any pointer, is is a null pointer. An integer 0 cast to a pointer is also a null pointer. A system could have many different (bit-wise) null pointers. They all compare equally to each other. They all compare unequally to any valid object/function. Recall this compare is done as pointers, not integers.
An integer constant expression with the value 0, or such an expression cast to type
void *, is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function. C11 §6.3.2.3 3
int x;
if (&x == NULL) ... // this is false
So after all that chapter and verse how to distinguish NULL from 0?
If the macro NULL is defined as an int 0 - it is game over - there is no difference between 0 and NULL.
If NULL is not an int, then code can use _Generic() to differentiate NULL and 0. This does not help OP's "Any change made can only be made within the function itself." requirement as that function accepts an int augment.
If NULL is an int that has a different bit-pattern than 0, then a simple memcmp() can differentiate.
I suspect the whole reason for this exercise is to realize there is no portable method to distinguish NULL from 0.
in C there is no type string, there is only a pointer to a char. When in C you need a string, you need to know how many characters are in the string, or have an indicator to see that you have reached the end of the string.
Traditionally there are two approaches to this requirements. In the C world the convention is to terminate the string with the \0 character. In the PASCAL world the convention is to use another variable to store the length of the string.
Java uses the PASCAL convention and stores the length of the string in another variable as the content of the string.
Both approaches have their merits. In the Java/PASCAL world, it is easy to know the length of the strings and a string can contain the \0 character. In C you can reuse the same character array for tail substrings etc.
In Java, we have a class named String which has a method called length().
In C, you need to have a \0 at the end of your string so you could know where your string ends. But in Java, this problem handled with the methodlength().
null means that a variable contains a reference to a space in memory that does not contain an object.
0 is a numeric data type with a value of 0.
Nothing doesn't really exist, however I think you may be viewing this as an empty String "" which is simply a String data type that does not contain a value.
If your looking at this from a Javascript paradigm it may be confusing. In Java variables are not truthy and falsey therefore the type is considered in comparisons.
0 is a number, you use it to check if a numeric value (int, short, float, double, etc.) is the number 0.
null is the value of a reference that points nowhere, you use it to make sure a reference does indeed reference something.
nothing is not part of Java.
The closest thing for nothing (for: no information at all) is the void declaration of a method. It states that the method returns literally nothing.
Note that 0, null and the empty string "" are values and thus contain information.
For example, 0 is the answer to "What is 5 subtracted from 5?" (among others).
null is the negative response to "Does this thing point to an object?".
""" could be the answer to "What is the longest sequenc of 'X's in your name?", unless your name is "Xanthippe".