52

I want to know the difference between str == NULL and str[0] == '\0':

int convert_to_float(char *str, double *num)
{
    if ((str == NULL) || (str[0] == '\0'))
        return(-1);

    *num = strtod(str, (char **)NULL);
    return(0);
}

I'm using gcc on Linux.

Kobi
  • 135,331
  • 41
  • 252
  • 292
john
  • 1,323
  • 2
  • 19
  • 31
  • 4
    @julio.alegria I wouldn't say that this check is too different from what you have in Java. In Java I would write `if (str == null || str.isEmpty())`, which is mostly similar to the line in C, except that the length test is done differently. – Malcolm Nov 30 '11 at 09:46
  • Note that NULL and '\0' are the **exact same thing.** The only difference between the two is whether you are dereferencing the pointer. `(NULL == '\0')` returns true. – user606723 Nov 30 '11 at 15:46
  • ...caveat: "on almost (but not) all systems," NULL is defined as 0. The C standards don't require this to be true, and there are estoteric systems in existence in which NULL != 0. NULL = (void*) 0 /* or some other number, but definitely (void*) */; 0 = (int)0; 0.0 = (float)0; '\0' = (char)0. – BRPocock Nov 30 '11 at 17:48
  • 1
    the first and 3rd answers are completely incorrect. There is a huge difference. One is the pointer being compared to a NULL pointer (points nowhere) and the other is a nul character delimited legal C string where str is a valid pointer. – RichieHH Dec 06 '11 at 17:33
  • @user606723 NULL and '\0' are quite different. On my machine `sizeof(NULL)`=4, `sizeof('\0')`=0. They may convert to the same value in a lot of contexts, but in some critical ones they do not. For example function resolution, `sizeof` and templates are just some of the tricky cases. – Michael Anderson Dec 07 '11 at 07:39
  • 3
    @MichaelAnderson: `NULL` can be either `0` or `(void*)0`; its size can be either the size of a pointer, or the size of an `int`. `sizeof('\0')` cannot be 0; it should be the same as `sizeof (int)`, since C character constants are of type `int`. – Keith Thompson Dec 07 '11 at 21:57
  • @KeithThompson oops that 0 was a typo it should have been 1. Ah, but I was compiling in C++, which may cause the difference there. I was thinking it was a C++ question .. so all my differences may disappear in C. (This may be one of those strange differences between C and C++) – Michael Anderson Dec 08 '11 at 00:53
  • @RichardRiley: The phrase "the first and 3rd answers" isn't necessarily meaningful. The order in which answers are displayed is not constant. – Keith Thompson Dec 08 '11 at 20:54

10 Answers10

110

str==NULL tells you whether the pointer is NULL.

str[0]=='\0' tells you if the string is of zero-length.

In that code, the test:

if ((str == NULL) || (str[0] == '\0'))

is used to catch the case where it is either NULL or has zero-length.


Note that short-circuiting plays a key role here: The point of the test is to make sure that str is a valid c-string with length at least 1.

  • The second test str[0] == '\0' will only work if str is not NULL.
  • Therefore, the first test str == NULL is needed to break out early when str is NULL.
Mysticial
  • 464,885
  • 45
  • 335
  • 332
  • `str[0]=='\0' tells you if the string is of zero-length.` Sure? – Nawaz Nov 30 '11 at 05:18
  • 14
    Zero-length if you were to print it. Indeed it could have more allocated space to it. – Mysticial Nov 30 '11 at 05:18
  • 3
    @Mysticial I would say because you said "checks whether the string is NULL". It's a pointer, and the way you described it sounds somewhat unclear. I didn't downvote either. I also don't know why this answer is downvoted. Let me offset those downvotes for you :) – Marlon Nov 30 '11 at 05:21
  • I have fixed that. I can see how that can be misleading/unclear. – Mysticial Nov 30 '11 at 05:22
  • @Mysticial: You said `Zero-length if you were to print it.` Does it not depend on *how* do I print it? :P – Nawaz Nov 30 '11 at 05:47
  • 12
    @Nawaz: Zero-length means `strlen(str) == 0`. – fredoverflow Nov 30 '11 at 06:06
  • I would phrase it "str[0]=='\0' tells you if the first character of the string is a NUL character (which indicates the string is zero-length)." Otherwise someone might get the impression that the first character somehow indicates the length of the string. – Firstrock Nov 30 '11 at 12:25
  • True. The statement "With length at least 1" is very misleading. "length" is usually interpreted as "what strlen() yields", not "the size of the buffer". – Kos Nov 30 '11 at 12:34
  • 1
    @Firstrock: I *wouldn't* phrase it that way; the null byte isn't the first character of the string, but rather, indicates that the string doesn't even have a first character. Probably a better approach is to explain how null-terminated strings work in general (not just zero-length strings). – ruakh Nov 30 '11 at 13:18
46

It's important to remember that str isn't really a "a string", but rather a pointer to the memory location where a char (a part of a string) is stored.

Next, we have to understand how the compiler sees all of these items. Let's look at their types:

  • str is of type char * (literally, "pointer to a char")
  • NULL is a null pointer constant (at least on my system, it's ((void*)0))
  • '\0' is a character constant (it's actually of type int, but don't worry about that; it's generally used in a context that requires a char value)

See the * in char * and void *? That tells the compiler that these are pointer types (which is a fancy way of saying that variables of this type don't hold the value, they just point at it). So when the compiler sees char *str, it knows that you might ask to do something like *str or str[0] (which both do the same thing). We'll get back to that, later.

You see, when you write str in a C program, the compiler knows that a variable called "str" is stored in a memory location, for example 0x0001. The code it generates goes to 0x0001 and fetches the value. That way, if you do something like

str + 1

Then the compiler will generate code that looks something like:

fetch the value from where str is stored (0x0001)
add 1 to that value

Which is something I'm sure you know. So now it should be obvious what this line says:

str == NULL

Since NULL is a null pointer constant, that line tests whether str is a null pointer (i.e., a pointer that doesn't point to anything).

So the compiler typically generates code like this:

fetch the value from where str is stored
check if that value is 0

Remember now, if you please, that we told the compiler that str is really a pointer type. So we're allowed to write this:

*str

And that makes the compiler generate this:

fetch the value from where str is stored
now use that value as a memory address and fetch what is stored there

So if str held 0x0200, then we would get the value from the memory address 0x0200. Note that the compiler doesn't really care if a string is really stored there or not.

(I'm going to assume you know that str[0] is the same as *str. It makes it easier to explain what's going on.)

How about this, then?

*str == '\0'

So that line is really, in effect:

*str == (char) 0

Which makes the compiler generate this:

fetch the value from where str is stored
now use that value like a memory address and fetch the char that is stored there
check if the value of that fetched char is 0

To summarize:

  • Writing str == NULL tells you whether the pointer str is pointing at nothing.
  • Writing *str == '\0' tells you whether the pointer str is pointing at a an empty string (actually, pointing at a memory location holding a zero).

(A "string" is, by definition, "a contiguous sequence of characters terminated by and including the first null character", so if the very first character of a string is '\0', then the string is an empty string.)

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Shalom Craimer
  • 20,659
  • 8
  • 70
  • 106
  • I've edited this answer to correct some factual errors. In particular, a string *is not* a pointer. – Keith Thompson Dec 06 '11 at 19:07
  • While the answer is more "correct", it's now more confusing. Sometimes simplifications have to be used in order to explain concepts, no? – Shalom Craimer Dec 07 '11 at 07:01
  • Sorry, but saying that a string is a pointer isn't a simplification. It's just incorrect. – Keith Thompson Dec 07 '11 at 08:45
  • You're 100% right. It is incorrect. And yet, when you ask people what is `s` in the statement `char* s`, they will say it's a string. I'd rather speak "lies for children" so that the concepts are clear, instead of being correct. It's just the way I teach. – Shalom Craimer Dec 07 '11 at 11:03
  • Show some respect for your audience. You're not talking to children. The correct concepts aren't that difficult. And how do you explain the result of `sizeof "hello, world"`? K&R and the [comp.lang.c FAQ](http://c-faq.com) manage to explain this stuff clearly without lying. – Keith Thompson Dec 07 '11 at 18:10
  • Well, no disrespect was intended. I guess you've got your way, and I've got mine. Could we just agree that we disagree? – Shalom Craimer Dec 07 '11 at 21:49
  • Your answer is much better now, thanks. One small quibble: the OP didn't actually call `str` "a string" (unless the name was meant to imply that). Oh, and character constants are of type `int`. And "pointer type" would be clearer and more accurate than "reference type" (they're distinct concepts in C++). – Keith Thompson Dec 08 '11 at 05:00
  • 1
    I've edited this answer again, trying to keep the spirit of your original. (BTW, it's possible that I misunderstood some previous versions and overreacted a bit.) – Keith Thompson Dec 08 '11 at 21:03
27

Essentially

  • str == NULL determines if str is a NULL pointer
  • str[0] == '\0' determines if str is a 0 length c style string

When you combine them you are checking if it NULL or empty. This allows the function to eliminate both forms of empty data at the start of the method

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • 5
    +1 key word is "pointer" ... the other answer is missing that –  Nov 30 '11 at 05:19
  • 2
    also: you can't de-reference str if it is NULL .. that's why the test against NULL needs to come first. The second test is checking a value in the memory location str is pointing to. –  Nov 30 '11 at 05:29
  • 1
    "str[0] == '\0' determines if str is a 0 length c style string" may lead a C newbie to believe the first character of the string holds the length of the string. Rather, the condition indicates that the first character of the string is NULL, and as a result of the C string convention, the length is 0. – Firstrock Nov 30 '11 at 12:20
8

str == NULL checking str is NULL-pointer (pointer to nowhere)

str[0] == '\0' (if not NULL-pointer) checking first str element has 0-value (string without characters only 0-terminated)

Tilo
  • 33,354
  • 5
  • 79
  • 106
triclosan
  • 5,578
  • 6
  • 26
  • 50
7

str==NULL tells you whether the string is NULL.

*str=='\0' tells you if the string is of zero-length.

Note: This answer is a play on Mystical's 15 second answer which had str=='\0'. Of course changes made in the first 3 or 4 minutes aren't shown and he fixed it ಠ_ಠ.

Community
  • 1
  • 1
Matt Joiner
  • 112,946
  • 110
  • 377
  • 526
6

str == NULL means "str points to memory address zero" (or whatever address is NULL on your system). Typically this means there is no string at all.

str[0] == '\0' means "the first character of str is character zero" (which marks the end of the string). This would mean there's a string, but it's empty. Think of an empty cup versus no cup at all; same idea.

In other languages you might write str == null vs str == "". They mean two different things. It's especially important to understand the difference in C, since trying to use a NULL pointer will crash the program.

Rena
  • 3,923
  • 3
  • 22
  • 19
4

str == NULL it means that string having NO REFERENCE of string, because it's pointer is Null(means address of string is null).

str[0] == '\0'-- means string with 0 length.

Please let me know if any thing is wrong in this explanation or you still have the doubt.

Sanoj Kashyap
  • 5,020
  • 4
  • 49
  • 75
3
str == NULL 

means that str is not pointing to any adress = pointer is empty.

and str[0] == '\0' str is pointing to a valid adress and this line check if the first char (ie str[0]) is the digit 0 ( the ascii value of '\0') wich means the end of the string. then the string is empty. (there is no character in str : the first one is the end character)

Hicham
  • 983
  • 6
  • 17
  • 5
    Sorry, but that's completely untrue. For the "short-circuit" operands `||` and `&&`, C requires that the operand on the left be evaluated first. – ruakh Nov 30 '11 at 13:22
2

1 -> str == NULL determines if str is a NULL pointer 2 -> str[0] == '\0' determines if str is a 0 length c style string

so in this if ((str == NULL) || (str[0] == '\0')) shortcircuiting of OR operator come into picture as it ensures either string is not pointing to anything or to empty string..

Sanoj Kashyap
  • 5,020
  • 4
  • 49
  • 75
Anshul garg
  • 233
  • 2
  • 6
0

C# equivalent of it is:

if (string.IsNullOrEmpty(str))
{

}

Simple meaning is whether the string is NULL or an empty string.

Daniel Roethlisberger
  • 6,958
  • 2
  • 41
  • 59
Estefany Velez
  • 328
  • 4
  • 18