Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
c++book1.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
1.83 Mб
Скачать

3.2.1 Круглые скобки

Скобками синтаксис С++ злоупотребляет; количество спосо­бов их использования приводит в замешательство: они применя­ются для заключения в них параметров в вызовах функций, в них заключается тип в преобразовании типа (приведении к типу), в именах типов для обозначения функций, а также для разрешения конфликтов приоритетов. К счастью, последнее требуется не слишком часто, потому что уровни приоритета и правила ассоци­ативности определены таким образом, чтобы выражения "работали ожидаемым образом" (то есть, отражали наиболее привычный спо­соб употребления). Например, значение

if (i<=0 !! max<i) // ...

очевидно. Тем не менее, всегда, когда программист сомне­вается относительно этих правил, следует употреблять скобки, и некоторые программисты предпочитают немного более длинное и менее элегантное

if ( (i<=0) !! (max<i) ) // ...

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

if (i&mask == 0) // ...

не происходит применения маски mask к i и последующей проверки результата на ноль. Поскольку == имеет приоритет вы­ше, чем &, выражение интерпретируется как i&(mask==0). В этом случае скобки оказываются важны:

if ((i&mask) == 0) // ...

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

if (0 <= a <= 99) // ...

Оно допустимо, но интерпретируется оно как (0<=a)<=99, где результат первого подвыражения или 0 или 1, но не a (если только a не равно 1). Чтобы проверить, лежит ли a в диапазоне

0...99, можно написать

if (0<=a && a<=99) // ...

3.2.2 Порядок вычисления

Порядок вычисления подвыражений в выражении неопределен. Например

int i = 1;

v[i] = i++;

может вычисляться или как v[1]=1, или как v[2]=1. При отсутствии ограничений на порядок вычисления выражения может генерироваться более хороший код. Было бы замечательно, если бы компилятор предупреждал о подобных неоднозначностях, но большинство компиляторов этого не делают.

Относительно операций && и !! гарантируется, что их левый операнд вычисляется раньше, чем правый. Например, b=(a=2,a=1) присвоит b 3.В #3.3.1приводятся примеры использования&& и !!. Заметьте, что операция следования , (запятая) логически отличается от запятой, которая используется для разделения параметров в вызове функции. Рассмотрим

f1(v[i],i++); // два параметра

f2( (v[i],i++) ) // один параметр

В вызове f1 два параметра, v[i] и i++, и порядок вычис­ления выражений-параметров неопределен. Зависимость выражения -параметра от порядка вычисления - это очень плохой стиль, а также непереносимо. В вызове f2 один параметр, выражение с запятой, которое эквивалентно i++.

С помощью скобок нельзя задать порядок вычисления. Нап­ример, a*(b/c) может вычисляться и как (a*b)/c, поскольку * и / имеют одинаковый приоритет. В тех случаях, когда важен по­рядок вычисления, можно вводить дополнительную переменную, например, (t=b/c,a*t).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]