эта масса кода сводится к: (потому что большая часть его устраняется с помощью последовательностей `'#if 0' ... '#endif')
#include <unistd.h> // for the 'sleep()' function
int main( void )
{
for (int i = 0; i < 1000000; i++)
{
if ( 0 == (i % 5 ) )
{
sleep(10);
}
}
}
где: я компилирую в Ubuntu Linux 18.02
вот как я скомпилировал код:
gcc -ggdb -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled2.c"
вот как я связал код:
gcc -ggdb -Wall -o "untitled2" "untitled2.c"
Примечание: -ggdb
в этом случае код будет содержать максимальную отладочную информацию для отладчика gdb
после компиляции / компоновки, результирующий размер исполняемого файла может быть найден с помощью:
ls -al untitled2.c
, что приводит к: [ 1115]
-rwxrwxrwx 1 richard richard 182 Mar 4 20:54 untitled2.c
182 байта не похожи ни на 204k, ни на 40k
Пожалуйста, опубликуйте свой компилятор, свою ОС, и вы скомпилировали + ссылку в исполняемый файл dynamic
(по умолчанию) или [ 118] исполняемый
Я предпочитаю помещать наиболее распространенный путь сначала, и я твердо уверенным во вложенном сокращении, таким образом, я буду повреждаться, продолжиться или возвратиться вместо elsing, когда это возможно. Я обычно предпочитаю тестировать против положительных условий или инвертирования [и имя] отрицательные условия как положительное.
if (condition)
return;
DoSomething();
я нашел, что, решительно уменьшая использование еще моего кода более читаемо и удобен в сопровождении и когда я еще действительно должен использовать почти всегда превосходный кандидат на более структурированный оператор переключения.
Если один из двух путей очень короток (приблизительно 1 - 10 строк), и другой намного длиннее, я следую правило Holub, упомянутое здесь , и вставляю более короткую часть кода если. Это помогает видеть если/еще поток на одном экране при рассмотрении кода.
, Если это не возможно, то я структурирую для создания условия максимально простым.
Можно обычно делать условие положительным, еще не передвигая если / блоки.
Изменение
if (!widget.enabled()) {
// more common
} else {
// less common
}
к
if (widget.disabled()) {
// more common
} else {
// less common
}
Программное обеспечение является получением знаний. Вы кодируете чье-то знание того, как сделать что-то.
программное обеспечение должно соответствовать тому, что является "естественным" для проблемы. Когда в сомнении, спросите кого-то еще и посмотрите то, что люди на самом деле говорят и делают.
Что относительно ситуации, где "общий" случай, ничего не делают? Что тогда
if( common ) {
// pass
}
else {
// great big block of exception-handling folderol
}
Или Вы делаете это?
if( ! common ) {
// great big block of except-handling folderol
}
"всегда положительное" правило не действительно, что Вы хотите сначала. Вы хотите посмотреть на правила больше как следующее.
Я думаю, что для единственной переменной не оператор достаточно прост, и называющие проблемы начинают быть более релевантными.
Никогда не называют переменную not_X, если нуждающееся использование тезаурус и находит противоположное. Я видел много ужасного кода как
if (not_dead) {
} else {
}
вместо очевидного
if (alive) {
} else {
}
Тогда, можно нормально использовать (очень читаемый, никакая потребность инвертировать блоки кода)
if (!alive) {
} else {
}
, Если мы говорим о большем количестве переменных, я думаю, что лучшее правило состоит в том, чтобы упростить условие. Через некоторое время проекты имеют тенденцию получать условия как:
if (dead || (!dead && sleeping)) {
} else {
}
, Который переводит в [1 110]
if (dead || sleeping) {
} else {
}
Всегда, обращают внимание на то, на что похожи условия и как упростить их.
Я знаю, что это не точно, что Вы ищете, но... Много разработчиков использует "защитный пункт", то есть, отрицание, "если" оператор, который убегает из метода как можно скорее. В той точке, не "еще" существует действительно.
Пример:
if (blah == false)
{
return; // perhaps with a message
}
// do rest of code here...
существует некоторый хардкор c/c ++/assembly парни там, которые скажут Вам, что Вы уничтожаете свой ЦП!!! (во многих случаях процессоры способствуют "истинному" оператору и попытке "выбрать следующую вещь с упреждением" сделать... так теоретически, любое "ложное" условие сбросит канал и пойдет микросекунды медленнее).
, По-моему, мы в точке, где "лучше" (более понятный) код побеждает за микросекунды процессорного времени.
Я соглашаюсь с Oli при использовании положительного выражения if, если это возможно.
Просто никогда не делают это:
if (somePositiveCondition)
else {
//stuff
}
я раньше видел это много в одном месте, я работал и раньше задавался вопросом, не понял ли один из кодеров, как не работает...
Когда я смотрю на подтверждение правильности данных, я пытаюсь сделать свои условия "белым списком" - то есть, я тестирую на то, что я приму:
if DataIsGood() then
DoMyNormalStuff
else
TakeEvasiveAction
, А не наоборот, который имеет тенденцию ухудшаться в:
if SomeErrorTest then
TakeSomeEvasiveAction
else if SomeOtherErrorCondition then
CorrectMoreStupidUserProblems
else if YetAnotherErrorThatNoOneThoughtOf then
DoMoreErrorHandling
else
DoMyNormalStuff
Если код должен проверить на состояние ошибки, я предпочитаю помещать тот код сначала и "успешный" второй код; концептуально, это сохраняет вызов функции и его код проверки ошибок вместе, который имеет смысл мне, потому что они связаны. Например:
if (!some_function_that_could_fail())
{
// Error handling code
}
else
{
// Success code
}
Это зависит от Вашего потока. Для многих функций я буду использовать предварительные условия:
bool MyFunc(variable) {
if (variable != something_i_want)
return false;
// a large block of code
// ...
return true;
}
, Если мне нужно к , делают что-то каждый случай, я буду использовать if (positive_clause) {} else {}
формат.
Я предпочитаю первый. Условие должно быть максимально простым, и это должно быть довольно очевидно, который более прост из условия и! условие
Две (противоречащих) кавычки учебника:
Помещенный самый короткий пункт, если/еще на вершине
- Allen Holub, "Достаточно Веревки для Стрельбы в в Ноге", p52
еще Поместил нормальный случай после если, а не после
- Steve McConnell, "Код Полный, 2-й редактор", p356
Для меня это зависит от условия, например:
if (!PreserveData.Checked)
{ resetfields();}
я склонен говорить с моим сам с тем, что я хочу, чтобы логика была и кодировала его к небольшой речи в моей голове.
Если у Вас должно быть несколько точек выхода, поместите их сначала и ясно дайте понять их:
if TerminatingCondition1 then
Exit
if TerminatingCondition2 then
Exit
Теперь мы можем сделать успехи с обычным материалом:
if NormalThing then
DoNormalThing
else
DoAbnormalThing
Необходимо всегда помещать наиболее вероятный случай сначала. Помимо того, чтобы быть более читаемым, это быстрее. Это также относится к операторам переключения.
!full == empty
) Я ужасен когда дело доходит до того, как я настроил если операторы. В основном я настроил его на основе того, что точно я ищу, который приводит все отличаться.
, если (userinput = пустой указатель) {
explodeViolently ();
} еще {
на самом деле наполняют;
}
или возможно что-то как
, если (1+1=2) {
действительно наполняют;
} еще {
explodeViolently ();
}
, Какой раздел, если/еще оператор на самом деле делает вещи для меня, является моей дурной привычкой.
Я всегда сохраняю наиболее вероятное сначала.
В Perl у меня есть дополнительная управляющая структура для помощи с этим. Инверсия если.
unless (alive) {
go_to_heaven;
} else {
say "MEDIC";
}
Как правило, если Вы значительно больше, чем другой, я делаю больший if
блок.
В первую очередь, давайте отложим ситуации, когда лучше избегать использования "еще" во-первых (я надеюсь, что все соглашаются, что такие ситуации действительно существуют и определение, что такие случаи, вероятно, должны быть отдельной темой).
Так, давайте предположим, что "еще" должно быть пункт.
Я думаю, что удобочитаемость/понятность налагает по крайней мере три ключевых требования или правила, которые, к сожалению, часто конкурируют друг с другом:
Чем короче первый блок ("если" блок), тем легче это для схватывания всего "если еще" конструкция. Когда, "если" блок достаточно длинен, становится слишком легко пропустить существование "еще" блока.
Когда, "если" и "еще" соединяет каналом, логически асимметричны (например, "нормальная обработка" по сравнению с ". ошибочная обработка"), в автономном, "если еще" конструкция это действительно не имеет значения очень, какой путь является первым и который является вторым. Однако, когда существуют несколько, "если еще" конструкции в близости друг к другу (включая вложение), и когда все они, "если еще" конструкции имеют асимметрию того же вида - именно тогда, очень важно расположить те асимметричные пути последовательно.
Снова, это может быть, "если... обычный тракт... еще... аварийный путь" для всех, или, "если... аварийный путь... еще... обычный тракт" для всех, но это не должно быть соединение этих двух вариантов.
Со всеми другими равными условиями, помещая обычный тракт сначала является, вероятно, более естественным для наиболее людей (я думаю, что это больше о психологии, чем эстетика :-).
Выражение, которое запускается с отрицания обычно, менее читаемо/понятно, чем выражение, которое не делает.
Так, у нас есть эти три конкурирующих требования/правила, и реальный вопрос: кто из них более важен, чем другие. Для Allen Holub правило № 1 является, вероятно, самым важным. Для Steve McConnell - это - правило № 2. Но я не думаю, что можно действительно выбрать только одно из этих правил как единственная инструкция.
Я держал пари, что Вы уже предположили мои персональные приоритеты здесь (от способа, которым я заказал правила выше :-).
Мои причины просты:
Правило № 1 является безусловным и невозможным обойти. Если один из блоков является таким длинным, что он убегает экран - это "еще" должно стать блок. (Нет, это не хорошая идея создать функцию/метод механически только для сокращения числа строк в "если" или "еще" блок! Я предполагаю, что каждый блок уже имеет логически допустимое минимальное количество строк.)
Правило № 2 включает много условий: несколько, "если еще" конструкции, все имеющие асимметрию того же вида, и т.д. Таким образом, это просто не применяется во многих случаях.
Кроме того, я часто наблюдаю следующее интересное явление: когда правило № 2 действительно применяется и когда оно используется правильно, оно на самом деле не конфликтует с правилом № 1! Например, каждый раз, когда у меня есть набор того, "если еще" операторы с "нормальным по сравнению с аварийной" асимметрией, все "аварийные" пути короче, чем "нормальные" (или наоборот). Я не могу объяснить это явление, но я думаю, что это - просто знак хорошей организации кода. Другими словами, каждый раз, когда я вижу ситуацию, когда правила № 1 и № 2 находятся в конфликте, я начинаю искать "запахи кода", и как правило я действительно нахожу некоторых; и после рефакторинга - tada! никакой более болезненный выбор между правилом № 1 и правилом № 2, :-)
Наконец, правило № 3 затуманивают самый маленький объем, и поэтому наименее очень важно.
Кроме того, как mentined здесь другими коллегами, часто очень легко "обмануть" с этим правилом (например, записать, "если (отключено)", вместо "если (! включенный)...").
Я надеюсь, что кто-то может иметь некоторый смысл этого опуса...
Предсказание ветвлений Intel Pentium выбирает инструкции с упреждением для "если" случай. Если это вместо этого следует, "еще" перейдите: это имеет сброс конвейер инструкции, вызывая останов.
, Если Вы заботитесь много о производительности: вставьте наиболее вероятный результат 'если' пункт.
Лично я пишу это как
if (expected)
{
//expected path
}
else
{
//fallback other odd case
}
Если бы Вы имеете, и истинные и ложные условия тогда я выбрал бы положительное условное выражение - Это уменьшает беспорядок, и в целом я верю, делает Ваш код легче читать.
, С другой стороны, при использовании языка, такого как Perl, и особенно если ложное условие является или состоянием ошибки или наиболее распространенным условием, можно использовать, 'если' структура, которая выполняет блок кода, если условие не верно (т.е. противоположность если):
unless ($foo) {
$bar;
}