Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Язык Си. Лабораторные работы / Справочник. Часть 1 (СПбГУТ).doc
Скачиваний:
49
Добавлен:
10.09.2019
Размер:
949.25 Кб
Скачать

2.2.3. Рекомендации по программированию

Рекомендации, содержащиеся в данном разделе, можно разделить на две категории. К первой из них можно отнести рекомендации общего характера, а ко второй – рекомендации, связанные с организацией разветвлений.

1. Не останавливайтесь на первом полученном решении.

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

Постановка задачи.

Вычислить значение величины “y”, заданной следующим образом

max(a, b) при a<0,

у =

min(a, b) при a≥0.

Решение.

Первый вариант.

Форма, в которой представлена постановка задачи, “навязывает” определённый алгоритм её решения. В целом решение является разветвлением на два направления, что требует использования инструкции if...else. Каждая из ветвей этого разветвления требует организовать разветвление на два направления. Это необходимо один раз для вычисления max(a, b), а второй раз – min(a, b). Таким образом, необходимые действия можно реализовать с помощью вложенных инструкций if...else. Причём внешняя инструкция if...else содержит внутренние инструкции в обеих своих ветвях. Фрагмент программы, реализующей это разветвление, представлен ниже

if(a < 0)

if(a > b)

y = a;

else

y = b;

else

if(a < b)

y = a;

else

y = b;

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

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

Выполним, так называемый, рефакторинг, который состоит в модернизации существующего программного кода с целью улучшения его структуры.

Второй вариант.

Анализ программного кода, приведённого выше, показывает, что алгоритмы вычисления max(a, b) и min(a, b) могут быть вынесены из внешней инструкции if ... else в линейную часть программы. Математическая формализация предлагаемой операции имеет следующий вид

mn = min(a, b),

mx = max(a, b),

mx при a < 0,

y =

mn при a ≥ 0.

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

if(a < b)

mn = a;

else

mn = b;

if(a >= b)

mx = a;

else

mx = b;

if(a < 0)

y = mx;

else

y = mn;

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

Третий вариант.

Рассмотрим возможность продолжить рефакторинг. Основанием для этого является похожесть алгоритмов вычисления max(a,b) и min(a,b). Можно попытаться объединить эти алгоритмы. В результате получим программный код, приведённый ниже.

if(a < b) {

mn = a ;

mx = b ;

}

else

{

mn = b ;

mx = a ;

}

if ( a < 0 )

y = mx ;

else

y = mn ;

2. Критически относитесь к возможности с помощью одного единственного алгоритма решить несколько задач.

Выше был рассмотрен пример вполне допустимого объединения решения двух задач (max(a, b) и min(a, b)) в одном алгоритме. Однако такое объединение скорее можно считать исключением, чем правилом. Часто подобное объединение приводит к решениям, которые вряд ли могут считаться удачными. В качестве примера приведем решение задачи, содержащееся в одном из задачников.

Постановка задачи.

Даны три числа a, b, c. Присвоить переменной m1 наименьшее из них, переменной m2 – среднее, переменной m3 – наибольшее.

Решение.

Решение, содержащее на внешнем уровне только одну инструкцию if ... else, имеет следующий вид.

if(a < b)

if(a > c)

{

m1 = c;

m2 = a;

m3 = b;

}

else if(b < c)

{

m1 = a;

m2 = b;

m3 = c;

}

else

{

m1 = a;

m2 = c;

m3 = b;

}

else if(a < c)

{

m1 = b;

m2 = a;

m3 = c;

}

else if(b < c)

{

m1 = b;

m2 = c;

m3 = a;

}

else

{

m1 = c;

m2 = b;

m3 = a;

}

По нашему мнению полученное решение нельзя признать удачным. Программный код трудно читать.

При решении этой задачи предпочтительнее идти по другому пути. Из постановки задачи следует, что она содержит в себе три подзадачи:

  • вычисление max(a, b, c),

  • вычисление min(a, b, c),

  • вычисление среднего из трёх чисел.

Поэтому решение всей задачи целесообразно представлять как простую совокупность трёх отдельных решений. Затем, в случае необходимости выполнить рефакторинг полученного решения. Оставляем такое решение задачи в качестве самостоятельной работы.

Приводимые далее рекомендации непосредственно относятся к организации разветвлений.

3. При программировании разветвлений на два направления стандартным решением является инструкция if ... else.

4. При программировании многовариантных разветвлений предпочтительнее использовать переключатель switch и вложенные цепочки if  else if.

5. Программный код обязательно должен быть структурирован. Разветвление следует выделять с помощью отступов.