У меня есть несколько циклов, которые мне нужны в моей программе. Я могу написать псевдокод, но я не совсем уверен, как писать их логически.
Я нуждаюсь -
if (num is a multiple of 10) { do this }
if (num is within 11-20, 31-40, 51-60, 71-80, 91-100) { do this }
else { do this } //this part is for 1-10, 21-30, 41-50, 61-70, 81-90
Это для настольной игры «Змеи и лестницы», если мой вопрос имеет больше смысла.
Я представляю себе первый оператор if, который мне нужно использовать по модулю. Было if (num == 100%10)
бы правильно?
Второй я понятия не имею. Я могу написать это как if (num > 10 && num is < 21 || etc.)
, но должно быть что-то умнее этого.
c++
comparison
conditional-statements
integer-arithmetic
user3419168
источник
источник
Ответы:
Для первого, чтобы проверить, является ли число многократным использованием:
Для второго:
Но это довольно сложно, и вам может быть лучше просто перечислить параметры явно.
Теперь, когда вы получили лучшее представление о том, что делаете, я бы написал вторую как:
Это та же логика, но с помощью функции мы получаем более четкое представление о том, что она означает.
источник
if((num - 1) / 10) % 2 == 1 && num < 100)
- Я бы заплакал, если бы увидел это.num >= 11
что (1) нижний предел запрещен, и (2)%
для отрицательного числа также возвращает отрицательное число. (Я должен признать, что использование& 1
здесь «безопаснее», но такжеgetRow(num) % 2 == 0
функцию, чтобы было кристально ясно, какова цель.bool inEvenRow(int num){ return getRow(num) % 2 ==0;}
Уловка здесь состоит в том, чтобы найти некоторую общность между диапазонами. Конечно, вы всегда можете воспользоваться методом «грубой силы»:
Но вы можете заметить, что если вычесть
1
изnum
, у вас будут диапазоны:Другими словами, все двузначные числа, первая цифра которых нечетная. Затем вам нужно придумать формулу, которая это выражает. Вы можете получить первую цифру, разделив ее на 10, и проверить, что она нечетная, проверив остаток 1 при делении на 2. Собираем все вместе:
Учитывая компромисс между более длинным, но поддерживаемым кодом и более коротким «умным» кодом, я бы каждый раз выбирал более длинный и ясный. По крайней мере, если вы попытаетесь быть умным, пожалуйста, включите комментарий, который точно объясняет, чего вы пытаетесь достичь.
Это помогает предположить, что следующий разработчик, который будет работать над кодом, вооружен и знает, где вы живете. :-)
источник
&& isTensDigitOdd(num)
, возможно, с комментарием перед определением функции, объясняющим, что он делает. Если такой шаблон существует, комментарий, объясняющий причины этого шаблона, поучителен для ремонтопригодности imo.Если вы используете GCC или любой компилятор, поддерживающий диапазоны регистров, вы можете это сделать, но ваш код не будет переносимым .
источник
Это больше для будущих посетителей, чем для новичков. Для более общего, подобного алгоритму решения вы можете взять список начальных и конечных значений и проверить, находится ли переданное значение в одном из них:
Для простоты я использовал полиморфную лямбду (C ++ 14) вместо явного
pair
аргумента. Это также , вероятно , придерживаться использования<
и==
чтобы соответствовать стандартным алгоритмам, но она работает , как это до тех пор , какElem
была<=
определена для него. Во всяком случае, его можно использовать так:Там есть живой пример здесь .
источник
Первый простой. Вам просто нужно применить оператор по модулю к вашему значению num:
Поскольку C ++ оценивает каждое число, отличное от 0, как истинное, вы также можете написать:
Что касается второго, я думаю, это будет понятнее:
Шаблон повторяется каждые 20, поэтому вы можете вычислить по модулю 20. Все элементы, которые вам нужны, будут в строке, кроме тех, которые делятся на 20.
Чтобы получить и их, просто используйте num-1 или лучше num + 19, чтобы не иметь дело с отрицательными числами.
Предполагается, что шаблон повторяется вечно, поэтому для 111-120 он будет применяться снова и так далее. В противном случае вам нужно ограничить числа до 100:
источник
С парой хороших комментариев в коде его можно написать довольно кратко и читабельно.
источник
num % 10 == 0
это то же самое, чтоnum
и кратное 10.if (num % 10 == 0)
означает то же самое, что// Check if it's a multiple of 10
не должен поддерживать ваш код. Это всем известный антипаттерн.%
- это антипаттерн; очевидно, что это не так. На самом деле, если предположить, что многие из читателей этого поста будут новичками, обучение их такому стилю написания комментариев окажет негативное влияние на их развитие как программистов.Вы в основном сами объяснили ответ, но вот код на всякий случай.
источник
x < 41 x > 50
и поставьте скобки.operator&&
имеет более высокий приоритет, чемoperator||
, так что это нормально, но я почти уверен, что GCC все равно предупреждает об этом.10 < x < 21
как10 < x && x < 21
вместоx > 10 && x < 21
. Неравенство легче читать, если оно находится в том же порядке, в каком вы бы написали его математически.Возможно, вы слишком много думаете об этом.
Первая строка
if (x % 10)
работает, потому что (a) значение, кратное 10, вычисляется как '0', другие числа дают их остаток, (b) значение 0 в anif
считаетсяfalse
, любое другое значение считаетсяtrue
.Редактировать:
Чтобы переключаться вперед и назад в двадцатых годах, используйте тот же трюк. На этот раз решающее число
10
:x/10
возвращает любое число от 0 до 9 как0
, от 10 до 19 как1
и так далее. Проверка на четность или нечетность -& 1
говорит вам, четное это или нечетное. Так как ваши диапазоны на самом деле равны «от 11 до 20», вычтите 1 перед тестированием.источник
Призыв к удобочитаемости
Хотя у вас уже есть хорошие ответы, я хотел бы порекомендовать технику программирования, которая сделает ваш код более читабельным для будущего читателя - это можете быть вы через шесть месяцев, коллега, попросивший провести обзор кода, ваш преемник, .. .
Это делается для того, чтобы превратить любые «умные» утверждения в функцию, которая точно показывает (своим именем), что она делает. Хотя есть незначительное влияние на производительность (из-за «накладных расходов на вызов функций»), оно действительно незначительно в такой игровой ситуации.
Попутно вы можете дезинфицировать свои входные данные - например, проверить "недопустимые" значения. Таким образом, у вас может получиться такой код - посмотрите, насколько он читабельнее? «Вспомогательные функции» можно где-то спрятать (не обязательно, чтобы они были в основном модуле: из их названия ясно, что они делают):
источник
YES
иNO
?TRUE
,True
илиtrue
? И какие файлы заголовков мне нужно было бы включить в обычный C? Так что я свернул свой. Интересно, это то, что вызвало отрицательный голос ...Для первого:
будет применяться к:
Для второго:
будет подавать заявку на:
В основном мы сначала делаем,
x-1
чтобы получить:Затем делим их на,
10
чтобы получить:Поэтому мы проверяем, не является ли этот результат нечетным.
источник
Вы можете попробовать следующее:
источник
Я знаю, что на этот вопрос так много ответов, но я все равно брошу сюда свой ...
Взято из полного кода Стива МакКоннелла. , 2-е издание: «Таблицы доступа по лестнице:
Еще один вид доступа к таблицам - это ступенчатый метод. Этот метод доступа не такой прямой, как структура индекса, но он не тратит так много места для данных. Общая идея ступенчатых структур, показанная на рис. 18-5, состоит в том, что записи в таблице действительны для диапазонов данных, а не для отдельных точек данных.
Рисунок 18-5 Лестнично-ступенчатый подход классифицирует каждую запись, определяя уровень, на котором она попадает в «лестницу». «Шаг» определяет его категорию.
Например, если вы пишете программу выставления оценок, диапазон ввода «B» может составлять от 75 до 90 процентов. Вот несколько классов, которые вам, возможно, придется когда-нибудь запрограммировать:
Чтобы использовать метод ступенчатой лестницы, вы помещаете верхний предел каждого диапазона в таблицу, а затем пишете цикл, чтобы сравнить результат с верхним пределом каждого диапазона. Когда вы находите точку, в которой оценка сначала превышает верхнюю границу диапазона, вы знаете, какова оценка. При использовании техники ступенчатой лестницы вы должны быть осторожны, чтобы правильно обрабатывать конечные точки диапазонов. Вот код в Visual Basic, который выставляет оценки группе студентов на основе этого примера:
Хотя это простой пример, вы можете легко обобщить его для работы с несколькими студентами, несколькими схемами выставления оценок (например, разными оценками для разных уровней баллов по разным заданиям) и изменениями в схеме выставления оценок ».
Код завершен , 2-е издание, страницы 426–428 (Глава 18).
источник
Как отмечали другие, упрощение условий не ускорит компиляцию или выполнение, а также не обязательно поможет с удобочитаемостью.
Это может помочь сделать вашу программу более гибкой, если позже вы решите, что вам нужна версия игры для малышей на доске 6 x 6 или расширенная версия (в которую вы можете играть всю ночь) на доске 40 x 50. .
Поэтому я бы закодировал это следующим образом:
Да, это многословно, но ясно, что происходит на игровом поле.
Если бы я разрабатывал эту игру для отображения на телефоне или планшете, я бы сделал переменные ROWS и COLUMNS вместо констант, чтобы их можно было устанавливать динамически (в начале игры) в соответствии с размером и ориентацией экрана.
Я бы также позволил изменить ориентацию экрана в любое время, в середине игры - все, что вам нужно сделать, это переключить значения ROWS и COLUMNS, оставив все остальное (текущий номер квадрата, на котором находится каждый игрок, и начальные / конечные квадраты всех змей и лестниц) без изменений. Затем вам «просто» нужно красиво нарисовать доску и написать код для своей анимации (я предполагаю, что это было целью ваших
if
утверждений) ...источник
#define
#define
инструкций, похожих на функции, рекомендуется заключать аргументы в скобки там, где они появляются в раскрытии. Так что вместо#define finished(num) (num == lastSquare)
тебя надо писать#define finished(num) ((num) == lastSquare)
. Причина в том, что если вы используете такую инструкцию с выражением, содержащим оператор с достаточно низким приоритетом, вы не получите ожидаемого ответа. В этом случае, если вы не используете лишние круглые скобки, тоfinished(a & b)
раскрывается,(a & b == lastSquare)
что почти наверняка не то, что вам нужно.