Идиоматический способ проверки на ненулевое - PullRequest
5 голосов
/ 26 октября 2011

Когда я хочу проверить, является ли значение 0 в C, как это идиоматически сделано?

  • if (!num)
  • if (num == 0)

Ответы [ 8 ]

15 голосов
/ 26 октября 2011

Хотя это вопрос вкуса, я считаю, что это в значительной степени зависит от намерения. Если значение будет использоваться как логическое значение, ! в порядке. Если значение что-то считает, равенство имеет больше смысла.

if (!isVisible) {...}
if (isVisible == 0) {...} // Intention not as clear as line above.

if (numberOfItems == 0) {...}
if (!numberOfItems) {...} // Intention not as clear as line above.
6 голосов
/ 26 октября 2011

Я всегда предпочитаю второй способ:

if (num == 0)

Поскольку num == 0 или ptr == NULL оценивается как логическое значение, которое является намерением.Компилятор Java применяет эту форму, а компиляторы C / C ++ - нет.

Худшим примером этого может быть:

if (!strcmp(str, "something"))

, который действительно скрывает свои намерения как семейство strcmpфункций не возвращают логическое значение, они возвращают положительное, нулевое или отрицательное значение (как указано @JoachimPileborg).

Однако, если int используется для представления логического типа, то C неиметь встроенный тип для, тогда эта форма в порядке:

if (!b)

Но это можно сделать самодокументированием, создав собственный тип:

typedef int bool;
#define true 1
#define false 0

bool b = true;
if (!b)
{
   ... etc
}
3 голосов
/ 26 октября 2011

Что бы ни говорили вам другие с ИСКЛЮЧЕНИЕМ!

Не делайте этого с float и double.IEEE 754 float s / double s / long double s (наиболее часто используемые) часто не содержат точных значений, поэтому сравнивать их напрямую с 0 глупо (или делать if (!floatValue))

Пример: http://ideone.com/PIUflA

float f = 0.3;
f -= 0.2;
f -= 0.1;

if (!f)
{
    printf("zero\n");
}
else
{
    printf("non zero\n");
}

if (f == 0)
{
    printf("zero\n");
}
else
{
    printf("non zero\n");
}

При неоптимизированной компиляции может вернуть (на ideone делает)

non zero
non zero

(если включить оптимизацию, компиляторможет предварительно вычислить некоторые значения с более высокой точностью и округлить их до 0)

2 голосов
/ 26 октября 2011

Я думаю, это зависит от контекста. Если переменная ссылается на логическое значение, лучше сначала выбрать. В противном случае второй лучше.

1 голос
/ 26 октября 2011

Для компилятора это не имеет значения, конечно.Для читателя это так.Поскольку обе формы используются другими людьми, вы должны привыкнуть к ним и распознать их.Лично я предпочитаю самую короткую форму, которая требует меньше времени (меньше токенов, особенно скобок), чтобы прочитать и понять.Особенно:

if (!ptr) {}
if (!strcmp(a,b)) {}

легче читать, чем

if (ptr != NULL) {}
if (strcmp(a,b) == 0) {}
of (0 == strcmp()) {}

Последняя форма делает меня физически больным.

0 голосов
/ 26 октября 2011

Мы можем поспорить, какой путь лучше, но идиоматический, хотя для того, что я могу сказать другими архаичными ответами, будет if(!num).

0 голосов
/ 26 октября 2011

!!value также будет работать, если вы хотите проверить, не является ли значение ненулевым.

!value оценивается как 1, когда значение = 0, и 0, когда значение ≠ 0.
Второе ! переворачивает это, заставляя !!value оценивать 1, когда значение ≠ 0, и 0, когда значение = 0.

0 голосов
/ 26 октября 2011

Это сделано, однако вы хотите, чтобы это было сделано, с точки зрения вашего стиля. Я не думаю, что это имеет значение до тех пор, пока вы последовательны, и ясно, что вы пытаетесь сделать, или если вы делаете это в тех случаях, когда это может звучать лучше в английском предложении и может акцентировать внимание на ваших действиях.

Ради ясности обычно у меня есть if (num == 0), поскольку для понимания того, что я делаю, когда я перебираю свой код, требуется меньше времени на размышления.

...