Управляющие операторы - if, switch, ?:
if - условный оператор, оператор выбора. Если результат выражения не равен 0 то выполняется блок после оператора, иначе присутствует(если нужно) оператор else.
if( выражение )
{
выполняется если выражение не равно 0
}
else
{
выполняется если выражение равно 0
}
Также допускается вложенность этих операторов, но большая вложенность усложняет чтение кода, и увеличивает вероятность ошибок.
Ниже функция которая выполняет деление двух вещественных чисел, с проверкой деления на ноль(если вы не знаете, на 0 делить нельзя, зачастую приводит к падению программы).
В данном случае результат деления будет неверным, если вторым аргументом будет 0., но вопрос обработки ошибок это совершенно отдельная тема.
float div(float a, float b) { if(b == 0.0f) return 0.0; return a / b; }
int max(int a, int b) { if(a > b) return a; return b; }
if(enemy_in_range()) attack(); else move_to_enemy();
if( (range_to_enemy() >= 10 ) && (range_to_enemy() <= 30 )) { if(laser_reloaded()) attack_by_laser(); else move_to_enemy(); } else if(range_to_enemy() < 10) attacked_by_bow(); else move_to_enemy();
/* * -1 - pressed n (no) * 0 - unknown * 1 - pressed y (yes) */ int getYesNo_v1(char aCh) { if(aCh == 'n') return -1; if(aCh == 'y') return 1; return 0; }
/* * -1 - pressed n/N (no) * 0 - unknown * 1 - pressed y/Y (yes) */ int getYesNo_v2(char aCh) { if(aCh == 'n' || aCh == 'N') return -1; if(aCh == 'y' || aCh == 'Y') return 1; }
!!Избегайте!! сложных выражений в операнде if
int i = 0; if(++i && i || isOk(i)) i = 0;
switch - оператор выбора.
switch( выражение )
{
case ? :
break;
default:
break;
}
выражение должно быть целочисленным. Оператор switch можно назвать оператором принятия решений, решение принимается основываясь на выражении и сравнивается с описаными константами в case, если же там нет требуемой константы и описан блок default то выполнение программы переходит в этот блок.
Выше вы видели примеры по if, посмотрите на последние 2 примера, getYesNo_v1(), getYesNo_v2(), ниже эти 2 примера с использованием оператора switch
/* * -1 - pressed n (no) * 0 - unknown * 1 - pressed y (yes) */ int getYesNo_v1(char aCh) { switch(aCh) { case 'n': return -1; case 'y': return 1; } return 0; }
/* * -1 - pressed n (no) * 0 - unknown * 1 - pressed y (yes) */ int getYesNo_v2(char aCh) { switch(aCh) { case 'n': case 'N': return -1; case 'y': case 'Y': return 1; } return 0; }
Как вы видите, в условиях когда нам нужно сделать выбор, основываясь на целоцисленном значении, которое можно сравнить с константами, то выбор в пользу switch очевиден.
Также в switch(может поддерживаться не всеми компиляторами), можно проверять на попадание значения в указанный диапазон.
/* * -1 - lower case * 0 - not char * 1 - upper case */ int getUpperLowerInfo(char aCh) { switch(aCh) { case 'a' ... 'z': return -1; case 'A' ... 'Z': return 1; } return 0; }
Управление роботом, который двигается к точка загрузки, загружается, потом двигается к точке разгрузки, затем опять к точка загрузки , и т.д.
// robot state switch(state) { case 0: // move to point of unloading { if(!is_point_unload()) move(); else state = 1; break; } case 1: // unloading { unloading(); if(empty()) state = 2; break; } case 2: // move to point of loading { if(!is_point_load()) move(); else state = 3; break; } case 3: // loading { loading(); if(full()) state = 0; break; } case 4: // stop doing default: { safe_mode(); break; } }
Тернарный оператор ?: - операнд_1 ? операнд_2 : операнд_3
Тернарным оператором он называется потому что у оператора 3 операнда.
Этот оператор возвращает некоторое выражение, основываясь на первом операнде. Если первый операнд не равен 0 то возвращается 2й операнд, иначе возвращается 3й операнд. Это некий аналог оператора if - else
К примеру вернуть максимальное значение у двух операндов a и b
int max = a > b ? a : b;
или тоже самое с помощью if-else
int max = 0; if(a > b) max = a; else max = b;
Тернарный оператор также поддерживает вложенность, но не рекомендую увлекаться, код должен быть простым, иначе увеличивается время его чтения, ухудшается возможность модификации из-за сложных выражений и т.д.
int val = 0; // так лучше не делать val = some_expr_a() ? (some_expr_b() ? 1 : -1) : (some_expr_c() ? 10); // лучше так if(some_expr_a()) val = some_expr_b() ? 1 : -1; else val = some_expr_c() ? 10;
Что нужно помнить при использовании тернарного оператора:
Избегайте операндов с различными типами
1 ? 'A' : 1;
В этом примере будет выведен тип char но мы еще не знаем тип первого операнда,
int val = 0; val = 1 ? 'A' : 1;
А вот здесь, мы знаем тип первого операнда(int), значит будет неявное приведение типа char в int.
Иногда вот такие неявные приведения типов могут сыграть злую шутку, и в коде будет потенциальная ошибка, ИЗБЕГАЕМ операндов с различными типами! На крайний случай, если так делать нужно, то используем явное приведение типа.
int val = 0; val = 1 ? (int)'A' : 1;
Вот это уже лучше, так как здесь мы явно приводим операнд к общему типу выражения, и другой программист читая этот код, поймет что вы это сделали намеренно, и знаете какой может быть результат, чего не скажешь о коде который был ранее, о котором можно подумать что вы допустили оплошность.
Или ниже второй пример, где явная ошибка, данные получаем не те которые ожидаем
short a = 300; short b = 400; char res = 0; // много строк кода res = 1 ? a : b;
Если подвести итог, то!
Избегайте сложных выражение везде где это возможно, в том числе и в условных операторах.
Избегайте выражений у которых операнды с различными типами, или же явно приводите их к общему типу выражения.
Оператор switch работает только с целочисленными значениями, и операнды для case должны быть также целочисленными константами. Но если вы попробуете подставить туда не целочисленный тип, вам об этом напомнит компилятор :-)
ВСЕ ПРОЧИТАЛИ ЭТО СВИДЕТЕЛЬСТВО О том, КАК Я ПОЛУЧИЛ ССУД ОТ ЮРИДИЧЕСКОЙ И НАДЕЖНОЙ КРЕДИТНОЙ КОМПАНИИ Меня зовут Кьерстин Лис, я искал ссуду для погашения своих долгов, все, с кем я встречался, обманывали и забирали мои деньги, пока я наконец не встретил г-на Бенджамина Брейл Ли Он смог дать мне ссуду в размере 450 000 рэндов и помог некоторым другим моим коллегам. Я говорю как самый счастливый человек во всем мире сегодня, и я сказал себе, что любой кредитор, который спасет мою семью из нашей бедной ситуации, я скажу имя всему миру, и я так счастлив сказать, что моя семья вернулся навсегда, потому что я нуждался в ссуде, чтобы начать свою жизнь с самого начала, так как я мать-одиночка с 3 детьми, и весь мир казался, что это висело на мне, пока я не имел в виду, что БОГ послал кредитора, который изменил мою жизнь и что из моей семьи, БОГ, боящийся кредитора, мистер Бенджамин, он был Богом Спасителем, посланным, чтобы спасти мою семью, и сначала я подумал, что это будет невозможно, пока я не получу ссуду, я пригласил его к моей семье получить -вместе вечеринка, от которой он не отказался, и я посоветую любому, кто действительно нуждается в ссуде, связаться с г-ном Бенджамином Брейлом Ли по электронной почте (247officedept@gmail.com), потому что он самый понимающий и добрый кредитор. когда-либо встречались с заботливым сердцем. Он не знает, что я делаю это, распространяя его доброжелательность ко мне, но я чувствую, что должен поделиться этим со всеми вами, связавшись с соответствующей кредитной компанией по электронной почте через: 247officedept@gmail.com или whatsapp + 1-989-394-3740. .
ОтветитьУдалить