Подтвердить что ты не робот

Замена вложенных операторов if

Это связано с главой красивого кода. И в этой главе я читал о вложенных ifs.

Автор говорил о глубоко вложенном ifs в качестве orginator ошибок и менее удобочитаемым. И он говорил о замене вложенных ifs аргументами case и таблицами решений.

Может ли кто-нибудь проиллюстрировать, как удалить вложенные ifs с помощью case (select case) и таблиц решений?

4b9b3361

Ответ 1

Ну, не прямо ответ на ваш вопрос, поскольку вы специально задаете вопрос о операторах switch/case, но вот аналогичный вопрос.

Инвертировать инструкцию "if" для уменьшения вложенности

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

Ответ 2

Один пример, который я всегда пытаюсь сделать, - это заменить сильно вложенные, если это так (на самом деле это не слишком слишком, но я видел их до 8 или 9 уровней в глубине души):

if (i == 1) {
    // action 1
} else {
    if (i == 2) {
        // action 2
    } else {
        if (i == 3) {
            // action 3
        } else {
            // action 4
        }
    }
}

с этим:

switch (i) {
    case 1:
        // action 1
        break;
    case 2:
        // action 2
        break;
    case 3:
        // action 3
        break;
    default:
        // action 4
        break;
}

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

Таблицы принятия решений, я считаю, просто устанавливают флажки, указывающие, какие действия необходимо предпринять позже. Раздел "позже" - это простое упорядочение действий на основе этих флагов. Я мог ошибаться (это будет не первый или последний раз: -).

Примером может быть (фаза установки флага может быть сложной, если, поскольку ее действия очень просты):

switch (i) {
    case 1:
        outmsg = "no paper";
        genmsg = true;
        mailmsg = true;
        phonemsg = false;
        break;
    case 2:
        outmsg = "no ink";
        genmsg = true;
        mailmsg = true;
        phonemsg = false;
        break;
    default:
        outmsg = "unknown problem";
        genmsg = true;
        mailmsg = true;
        phonemsg = true;
        break;
}

if (genmsg)
    // Send message to screen.
if (mailmsg)
    // Send message to operators email address.
if (phonemsg)
    // Hassle operators mobile phone.

Ответ 3

Как насчет цепных ifs?

Заменить

if (condition1)
{
    do1
}   
else
{
    if (condition2)
    {
        do2
    }
    else (condition3)
    {
        do3;

    }
}

с

if (condition1) {
   do1;
} else if (condition2) {
   do2;
} else if (condition3) {
   do3;
}

Это очень похоже на инструкцию switch для сложных условий.

Ответ 4

Сделайте условие в booleans и затем напишите логическое выражение для каждого случая.

Если код был:

if (condition1)
{
    do1
}   
else
{
    if (condition2)
    {
        do2
    }
    else (condition3)
    {
        do3;

    }
}

Можно записать его как:

bool cond1=condition1;
bool cond2=condition2;
bool cond3=condition3;

if (cond1) {do1;}
if (!cond1 and cond2) {do2;}
if (!cond1 and cond3) {do2;}

Ответ 6

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

function validate(){
  if(b=="" || b==null){
      alert("Please enter your city");
      return false;
  }

  if(a=="" || a==null){
      alert("Please enter your address");
      return false;
  }
  return true;
}

Ответ 7

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

Итак, вместо этого (используя пример @Pax):

if (i == 1) {
    // action 1
} else {
    if (i == 2) {
        // action 2
    } else {
        if (i == 3) {
            // action 3
        } else {
            // action 4
        }
    }
}

вы делаете что-то вроде этого:

void action1()
{
    // action 1
}

void action2()
{
    // action 2
}

void action3()
{
    // action 3
}

void action4()
{
    // action 4
}

#define NUM_ACTIONS 4

// Create array of function pointers for each allowed value of i
void (*actions[NUM_ACTIONS])() = { NULL, action1, action2, action3 }

// And now in the body of a function somewhere...
if ((i < NUM_ACTIONS) && actions[i])
    actions[i]();
else
    action4();

Если возможности для i не являются целыми числами с низким номером, вы можете создать таблицу поиска вместо прямого доступа к элементу i th массива actions.

Этот метод становится гораздо более полезным, чем вложенные операторы if или switch, когда вы принимаете решение по десяткам возможных значений.

Ответ 8

Если и операторы switch не являются чисто OO. Это условная процедурная логика, но очень хорошая работа! Если вы хотите удалить эти инструкции для более OO-подхода, объединить шаблоны "State" и "Descriptor" .

Ответ 10

Вложенные, если они эквивалентны логическому оператору AND

if (condition1)
{
    if (function(2))
    {
        if (condition3)
        {
            // do something
        }
    }
}

Эквивалентный код:

if (condition1 && function(2) && condition3)
{
    // do something
}

В обоих случаях, когда выражение оценивает значение false, последующее выражение не будет оцениваться. Например, если условие1 ложно, функция() не будет вызываться, а условие 3 не будет оцениваться.

Ответ 11

Другим примером, допустимым для некоторых языков, является

           switch true{
            case i==0
              //action
            break

            case j==2
             //action
            break

            case i>j
             //action
            break
           }