Как в C++ красиво реализовать множество условий?

В коде есть момент, который имеет много условий.
if (water[qX][qY] < water[x][y] && qX >= 0 && qY >= 0 && qX < room_size && qY < room_size && water[x][y] != 0) {...}


Как лучше оформить такой код для читабельного вида, но и что бы ресурсы не кушал чрезмерно много?
Так?:
if (qX >= 0 && qY >= 0 && qX < room_size && qY < room_size)
   if (water[qX][qY] < water[x][y] && water[x][y] != 0) {
       ...
   }

или даже так?:
if (qX >= 0 && qY >= 0)
   if (qX < room_size && qY < room_size)
      if (water[qX][qY] < water[x][y] && water[x][y] != 0) {
         ...
      }
  • Вопрос задан
  • 4521 просмотр
Решения вопроса 2
risik
@risik
Программист
Сложные условия следует разбивать на простые. равно как и слдожные функции следует разбивать на простые.

(qX >= 0 && qY >= 0 && qX < room_size && qY < room_size)

Это условие, как я вижу, проверяет вхождение я прямоугольник? Лучше всего в отдельную функцию. Повысит читаемость.
например так:
bool isInRoom(int qX, int qY, int room_size) 
{
  if (qX < 0)
    return false;
  if (qY < 0)
    return false;
  if (qX >= room_size)
    return false;
  if (qY >= room_size)
    return false;
  return true;
}


Боитесь за производительность - inline функцию. Затем так:
if (isInRoom(qX, qY, room_size) && water[qX][qY] < water[x][y] && water[x][y] != 0)
...


или так:
if (! isInRoom(qX, qY, room_size)) // проверка предусловия
  return;
if (water[qX][qY] < water[x][y] && water[x][y] != 0)
...
Ответ написан
Teivaz
@Teivaz
В подобных случаях я разделяю группы условий либо на временные пременные, либо на функции.
Например:
bool CanConsumePoint();
bool IsPointValid(Point pt);

bool pointInsideRectangle = (pointX > rectXMin) && (pointX < rectXMax) && (pointY > rectYMin) && (pointY < rectYMax);
bool pointTypeCompatible = (pointType == compatible) || (pointType == force);
bool pointValid = IsPointValid(currentPoint);
if (pointInsideRectangle && pointTypeCompatible && CanConsumePoint() && pointValid)
{
    ...
}

Так каждую переменную и метод можно отдельно рассматривать и легко понять за что каждая отвечает и при необходимости разобраться с логикой каждого элемента условия не вдаваясь в подробности остальных.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 4
Во вложенных условиях есть смысл, когда алгоритм ветвится, то есть куча else имеется.
Вообще, хорошо придерживаться стандартов. Если работаете в компании, спросите, как обычно в такие моменты поступают. Если пишете самостоятельно, делайте так, как считаете удобным. Просто придерживайтесь одного стиля.
Например, попробуйте сделать условие многострочным. Что-нибудь вроде:
if (
        water[qX][qY] < water[x][y]
    &&
        qX >= 0
    &&
        qY >= 0
    &&
        qX < room_size
    &&
        qY < room_size
    &&
        water[x][y] != 0
) {...}

Если приоритет выражений в условии идет не по порядку, то, используя такой метод, можно значительно повысить читаемость.
Ответ написан
Комментировать
Современным компиляторам нет разницы каким образом расположить условия - в одном if или в несколльких. Не верите? Попробуйте указать компилятору ключи, которые генерируют ассмемблерный код, и посмотрите, что разницы не будет.

gcc -S yousource.c - сгенерирует ассемблерный файл c помощью компилятора gcc

cl.exe /FAs /c yousource.c - сгенерирует ассемблерный файл c помощью компилятора командной строки Microsoft Visual C
Ответ написан
@dtho-dtho Автор вопроса
Строка 133 pastebin.com/tdiqwpSf

Вот сделал в отдельную функцию часть проверки... конечно мне кажется не очень красиво...
Хочется вообще весь блок начиная со строки 133 по 156 в отдельную функцию. Но ссылки, линки и прочее только сильнее запутают мне кажется.
Ответ написан
@askogorev
я бы написал так:

if (water[qX][qY] < water[x][y]      &&
    qX >= 0 && qY >= 0               &&
    qX < room_size && qY < room_size &&
    water[x][y] != 0) {
...
...
}


со следующей логикой:
* 1 строка - один логический if
* условия, которые имеют false чаще других - вверх (в случае false следующие условия уже не будут проверяться)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы