· Во-вторых, то, что лишние скобки способны повысить читабельность (даже если выражение сложное), является иллюзией,
· В-третьих, приоритеты логических операций (!, ||, &&) так же естественны, как и приоритеты арифметических операций, известных со школьной скамьи,
· В-четвертых, культура работы с логическими выражениями необходима программисту.
Он просто обязан с легкостью заменять выражение:
!(!was || !isNow) // Переменные was и isNow имеют тип bool
на:
was && isNow
а выражение: !(!was && ! isNow) на выражение: was || isNow.
Если вы не видите, что они эквивалентны, то устраните пробелы в знаниях школьного курса информатики (теоремы Де-Моргана. Когда-то нас учили запоминать их: "Крышка суммы равна произведению крышек" и "Крышка произведения равна сумме крышек").
У программиста не должно возникать желание добавить скобки в выражение:
if (GetName() && !isFinished || wasAuthorized && !isOk)
GetData();
потому, что приоритеты выполнения операций очевидны. Вернемся к примеру, взятому из курса MS. Если в ветвях условного оператора присутствует более сложная логика, как например, во фрагменте:
if (currentPage < totalPages) // Фрагмент взят из того же источника
{
currentPage += 1;
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
}
то, все равно, следующий вариант будет более предпочтительным:
e.HasMorePages = page < totalPages; // Идентификатор page проще, чем currentPage (не усложняйте имена локальных переменных)
if (e.HasMorePages)
page++;
Я вовсе не хочу сказать, что в Microsoft не умеют программировать. Просто там так много всего, что можно найти образцы как хорошего стиля, так и дрянного. В том же кладези мудрости (MS-курсе 2555) находим функцию (ее форматирование, соответствует оригиналу):
private void ShowPrinterInfo()
{
int lcv;
string printerInformation = "";
int printerCount;
string currentPrinter;
bool printerIsValid;
string defaultPrinterName = "";
bool printToFile;
// get the number of installed printers
printerCount = PrinterSettings.InstalledPrinters.Count;
for (lcv = 0;lcv <printerCount;lcv++) // Плохое форматирование. Три группы операторов цикла должны быть четко выделены
{
if(printDocument1.PrinterSettings.IsDefaultPrinter == true) // Условие не зависит от lcv !!!.
{
defaultPrinterName = PrinterSettings.InstalledPrinters[lcv];
}
}
for (lcv = 0;lcv <printerCount;lcv++)
{
currentPrinter = PrinterSettings.InstalledPrinters[lcv];
printDocument1.PrinterSettings.PrinterName = currentPrinter;
printerIsValid = printDocument1.PrinterSettings.IsValid;
printToFile = printDocument1.PrinterSettings.PrintToFile;
printerInformation = printerInformation + currentPrinter + "\n";
printerInformation = printerInformation + "IsValid = " + printerIsValid + "\n";
if (currentPrinter == defaultPrinterName)
{
printerInformation = printerInformation+"IsDefaultPrinter = "+true.ToString()+"\n";
}
else
{
printerInformation = printerInformation+"IsDefaultPrinter = "+false.ToString()+"\n";
}
printerInformation = printerInformation + "PrintToFile = "+printToFile + "\n\n";
}
MessageBox.Show(printerInformation, "Installed Printers",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
Если бы этот код создал троечник из соседней школы, то не стоило бы ломать копья, но он взят из официального курса (MOC — Microsoft Official Course). Проанализируйте код первого цикла for. Условие if внутри цикла абсолютно не зависит от перебираемых принтеров (то есть дурацкого индекса lcv) ! Результат:
· Если текущий документ выставлен на default-принтер (а по умолчанию это так), то все принтеры будут считаться default, и последний принтер всегда "побеждает",
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.