В чем разница между str == NULL и str [0] == '\ 0' в C? - PullRequest
52 голосов
/ 30 ноября 2011

Я хочу знать разницу между str == NULL и 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);
}

Я использую gcc в Linux.

Ответы [ 10 ]

109 голосов
/ 30 ноября 2011

str==NULL сообщает вам, является ли указатель NULL.

str[0]=='\0' сообщает вам, имеет ли строка нулевую длину.

В этом коде тест:

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

используется для определения случая, когда он имеет значение NULL или имеет нулевую длину.


Обратите внимание, что короткое замыкание играет ключевую роль: Суть теста состоит в том, чтобы убедиться, что str является допустимой c-строкой длиной не менее 1.

  • Второй тест str[0] == '\0' будет работать только в том случае, если str не равен NULL.
  • Таким образом, первый тест str == NULL необходим для раннего прорыва, когда str равен NULL.
46 голосов
/ 30 ноября 2011

Важно помнить, что str на самом деле не "строка", а указатель на область памяти, где хранится char (часть строки).

Далее мы должны понять, как компилятор видит все эти элементы.Давайте рассмотрим их типы:

  • str имеет тип char * (буквально, «указатель на char»)
  • NULL - константа нулевого указателя(по крайней мере, в моей системе это ((void*)0))
  • '\0' - это символьная константа (на самом деле это тип int, но не беспокойтесь об этом; обычно она используется в контексте, который требуетchar значение)

См. * в char * и void *?Это говорит компилятору, что это типы указателей (это причудливый способ сказать, что переменные этого типа не содержат значения, они просто указывают на него).Поэтому, когда компилятор видит char *str, он знает, что вы можете попросить сделать что-то вроде *str или str[0] (которые оба делают одно и то же).Мы вернемся к этому позже.

Видите ли, когда вы пишете str в программе на C, компилятор знает, что переменная с именем "str" ​​хранится в ячейке памяти, например, 0x0001,Генерируемый код переходит к 0x0001 и получает значение.Таким образом, если вы сделаете что-то вроде

str + 1

, то компилятор сгенерирует код, который будет выглядеть примерно так:

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

Я уверен, что вы это знаете.Так что теперь должно быть очевидно, что говорит эта строка:

str == NULL

Поскольку NULL является константой нулевого указателя, эта строка проверяет, является ли str нулевым указателем (т. Е. Указателем, который неуказать на что угодно).

Таким образом, компилятор обычно генерирует код, подобный следующему:

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

Запомните, если хотите, мы сказали компилятору, что str действительно тип указателя,Итак, мы можем написать это:

*str

И это заставит компилятор сгенерировать это:

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

Так что, если str содержит 0x0200, то мы получим значение из памятиадрес 0x0200.Обратите внимание, что компилятору на самом деле все равно, хранится ли там строка или нет.

(Я предполагаю, что вы знаете, что str[0] совпадает с *str. Это облегчаетчтобы объяснить, что происходит.)

А как насчет этого?

*str == '\0'

Итак, эта строка действительно:

*str == (char) 0

Что делает компиляторсгенерируйте это:

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

Подводя итог:

  • Запись str == NULL сообщает вам, указывает ли указатель str на что-либо.
  • Запись *str == '\0' сообщает вам, указывает ли указатель str на пустую строку (фактически, указывает на область памяти, содержащую ноль).

(«Строка» по определению является «непрерывной последовательностью символов, оканчивающихся и включающих первый нулевой символ», поэтому, если самый первый символ строки '\0', то строка является пустой строкой.)

27 голосов
/ 30 ноября 2011

По существу

  • str == NULL определяет, является ли str указатель NULL
  • str[0] == '\0' определяет, является ли str строкой стиля c длиной 0

Когда вы объединяете их, вы проверяете, пусто ли оно или нет.Это позволяет функции исключать обе формы пустых данных в начале метода

8 голосов
/ 30 ноября 2011

str == NULL проверка str является NULL-указателем (указатель в никуда)

str[0] == '\0' (если не NULL-указатель) проверка первого элемента str имеет значение 0 (строка без символов, заканчивается только 0)

7 голосов
/ 30 ноября 2011

str==NULL сообщает вам, является ли строка NULL.

*str=='\0' сообщает, имеет ли строка нулевую длину.

Примечание : Этот ответ является игрой на 15-секундном ответе Мистикала , в котором было str=='\0'.Конечно, изменения, сделанные в первые 3 или 4 минуты, не отображаются, и он исправил это ಠ_ಠ.

6 голосов
/ 30 ноября 2011

str == NULL означает "str указывает на нулевой адрес памяти" (или любой другой адрес в вашей системе, равный NULL). Обычно это означает, что строки вообще нет.

str [0] == '\ 0' означает «первый символ str - это нулевой символ» (который обозначает конец строки). Это будет означать, что есть строка, но она пуста. Подумайте о пустой чашке, а не о чашке вообще; та же идея.

На других языках вы можете написать str == null против str == "". Они означают две разные вещи. Особенно важно понимать разницу в C, поскольку попытка использовать нулевой указатель приведет к сбою программы.

4 голосов
/ 30 ноября 2011

str == NULL это означает, что строка не имеет ссылки на строку, потому что ее указатель равен нулю (означает, что адрес строки равен нулю).

str[0] == '\0' - означает строку длиной 0.

Пожалуйста, дайте мне знать, если что-то не так в этом объяснении, или у вас все еще есть сомнения.

3 голосов
/ 30 ноября 2011
str == NULL 

означает, что str не указывает ни на какой адрес = указатель пуст.

и str[0] == '\0' str указывает на действительный адрес, и эта строка проверяет, является ли первый символ (т. Е. Str [0]) цифрой 0 (значение ascii '\ 0'), что означает конец строки , тогда строка пуста. (в str нет символа: первый символ является конечным)

2 голосов
/ 13 декабря 2011

1 -> str == NULL определяет, является ли str нулевым указателем 2 -> str[0] == '\0' определяет, является ли str строкой стиля c длиной 0

так в этом if ((str == NULL) || (str[0] == '\0')) появляется короткое замыкание оператора ИЛИ, поскольку оно гарантирует, что строка ни на что не указывает или на пустую строку.

0 голосов
/ 08 декабря 2011

C # эквивалент этого:

if (string.IsNullOrEmpty(str))
{

}

Простое значение - является ли строка NULL или пустой строкой.

...