Правила программирования на Си и Си++


Не делайте вид, что Си поддерживает булевый тип (#define TRUE)


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

#define TRUE    1

#define FALSE   0

Любая отличная от нуля величина в Си означает истину, поэтому в следующем фрагменте f()

может вернуть совершенно законное значение "истина", которое не совпало с 1, и проверка даст отрицательный результат:

if( f() == TRUE ) // Вызов не выполняется, если f() возвращает

                  // значение "истина", отличное от 1.

    // ...

Следующий вариант надежен, но довольно неудобен. Я не думаю, что можно рекомендовать что-либо из подобной практики:

#define FALSE  0

if( f() !=  FALSE )

    // ...

В действительности здесь проявляется настоящая проблема, связанная с непониманием различий между языком Си и Паскалем. Си, в отличие от Паскаля, не поддерживает встроенный булевый тип, и полагать обратное означает просто навлечь на себя неприятности.



Часто необходимость в явном сравнении на истину или ложь можно устранить при помощи переименования:

if( я_сонливый(p) )

значительно лучше, чем:

if( я_сонливый(p) != FALSE )

Так как определения TRUE и FALSE

спрятаны в макросах, то хороший сопровождающий программист не может делать каких-либо предположений об их действительных значениях. Например, FALSE

может быть -1, а TRUE

— 0. И следственно, если функция возвращает в явном виде TRUE или FALSE, то наш прилежный сопровождающий программист должен будет потратить несколько дней, чтобы убедиться, что при проверке возвращаемого значения для каждого вызова используется явная проверка на равенство TRUE или FALSE (сравните для примера с простым логическим отрицанием !

перед вызовом). Следующий фрагмент:

if( я_сердитый() )

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

И напоследок —

имейте в виду, что следующий вариант не будет работать:

#define FALSE   0

#define TRUE    !FALSE

Операция !, подобно всем операторам отношений, преобразует операнд в 1, если он имеет значение "истина" (отличен от нуля), и 0, если наоборот. Предыдущий вариант идентичен следующему:

#define FALSE   0

#define TRUE    1

Вот более надежный, но нелепый вариант:

#define IS_TRUE(x)   ((x) == 0)

#define IS_FALSE(x)  ((x) != 0)




Содержание раздела