Почему вы иногда делаете две проверки на строку? - PullRequest
0 голосов
/ 01 ноября 2019

Я видел этот код:

char *str;
// Some code
if (! str || ! *str)
    return str;

Почему нужно проверить ! *str? Не достаточно ли if (! str)?

Ответы [ 2 ]

5 голосов
/ 01 ноября 2019

Это зависит от того, что вы хотите проверить:

  • Проверка !str str равна NULL.
  • !*str проверяет, что первый символ в strравен NUL байт ('\ 0')

В совокупности они возвращают 's', если s равно NULL, или s указывают на NUL-символ

1 голос
/ 01 ноября 2019

Давайте посмотрим на таблицу истинности:

str    *str    !str   !*str   !str || !*str
T      T       F      F       F
F      T       T      F       T
T      F       F      T       T
F      F       T      T       T

Так что, если str является указателем NULL, тогда !str будет истинным, а str всегда возвращается. Если str не является указателем NULL, то str будет возвращено, только если *str является терминатором NUL.

Обратите внимание, что вы можете использовать булеву алгебру, чтобы переписать это в !(str && *str). Скобка может быть выражена на английском языке как «непустая строка». Таким образом, все условие является «непустой строкой».

Обратите внимание, что оно работает из-за короткого замыкания , что означает, что если результат либо ||, либо && может бытьопределяется только левым операндом, тогда правый операнд не будет оцениваться. В противном случае разыменование может привести к неопределенному поведению, когда str является указателем NULL.

Здесь есть очень важная логическая вещь, на которую следует обратить внимание. То, что строка не «не пустая», не обязательно означает, что она пустая. Но это немного зависит от интерпретации. Есть три случая, и вот пример всех из них.

  • "Hello, World\0" - Определенно не пустой
  • "\0" - Определенно пустой
  • NULL - Определенно не «не пустой», но пустой?

Могу добавить, что это довольно странное условие для возврата str. Это не то, что вы обычно делаете.

...