Важно помнить, что 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'
, то строка является пустой строкой.)