//
n = p->size(); //
Поскольку приоритет обращения к значению ниже, чем оператора точка, часть обращения к значению следует заключить в скобки. Если пропустить круглые скобки, этот код поведет себя совсем по-иному:
//
//
*p.size(); //
Этот код пытается вызвать функцию-член size() объекта p. Однако p — это указатель, у которого нет никаких членов; этот код не будет откомпилирован.
Оператор стрелка получает операнд в виде указателя и возвращает l-значение. Оператор точка возвращает l-значение, если объект, член которого выбирается, является l-значением; в противном случае результат — r-значение.
Упражнение 4.20. С учетом того, что iter имеет тип vector, укажите, какие из следующих выражений допустимы, если таковые имеются. Объясните поведение допустимых выражений, и почему ошибочные не допустимы?
(a) *iter++; (b) (*iter)++; (с) *iter.empty()
(d) iter->empty(); (e) ++*iter; (f) iter++->empty();
4.7. Условный оператор
?:) (conditional operator) позволяет внедрять простые конструкции if...else непосредственно в выражение. Условный оператор имеет следующий синтаксис:
где — это выражение, используемое в качестве условия, а и — это выражения одинаковых типов (или типов, допускающих преобразование в общий тип). Эти выражения выполняются в зависимости от . Если условие истинно, то выполняется ; в противном случае выполняется . В качестве примера использования условного оператора рассмотрим код, определяющий, является ли оценка (grade) проходной (pass) или нет (fail):
string finalgrade = (grade < 60) ? "fail" : "pass";
Условие проверяет, не меньше ли оценка 60. Если это так, то результат выражения "fail"; в противном случае — результат "pass". Подобно операторам логического AND и OR (&& и ||), условный оператор гарантирует, что выполнено будет только одно из выражений, или .
Результат условного оператора — l-значение, если оба выражения l-значения или если они допускают преобразование в общий тип l-значения. В противном случае результат — r-значение.
Один условный оператор можно вложить в другой. Таким образом, условный оператор применяются как или как один или оба другого условного оператора. В качестве примера используем пару вложенных условных операторов для трехступенчатой проверки оценки, чтобы выяснить, является ли она выше проходной, просто проходной или непроходной.
finalgrade = (grade > 90) ? "high pass"
: (grade < 60) ? "fail" : "pass";
Первое условие проверяет, не выше ли оценка 90. Если это так, то выполняется выражение после ?, возвращающее литерал "high pass". Если условие ложно, выполняется ветвь :, которая сама является другим условным выражением. Это условное выражение проверяет, не меньше ли оценка 60. Если это так, то обрабатывается ветвь ?, возвращающая литерал "fail". В противном случае ветвь : возвращает литерал "pass".
Условный оператор имеет правосторонний порядок, т.е. его операнды группируются (как обычно) справа налево. Порядок объясняет тот факт, что правое условное выражение, сравнивающее grade со значением 60, образует ветвь : левого условного выражения.
Условный оператор имеет довольно низкий приоритет. Когда условный оператор используется в большом выражении, его, как правило, следует заключать в круглые скобки. Например, условный оператор нередко используют для отображения одного из значений в зависимости от результата проверки условия. Отсутствие круглых скобок вокруг условного оператора в выражении вывода может привести к неожиданным результатам:
cout << ((grade < 60) ? "fail" : "pass"); //
cout << (grade < 60) ? "fail" : "pass"; //