C1 (повышенный уровень, время – 30 мин)
Стр 1 из 4Следующая ⇒ Тема: Исправление ошибок в простой программе с условными операторами. Что нужно знать: · правила построения программы на Паскале[1], Бэйсике или Си · правила работы с переменными (объявление, ввод, вывод, оператор присваивания) · ветвление – это выбор одного из двух возможных вариантов действий в зависимости от того, выполняется ли некоторое условие; · на блок-схеме алгоритма ветвление изображается в виде блока-ромба с одним входом и двумя выходами:
· если условие, записанное внутри ромба, истинно (ответ «да» на вопрос «a=b?»), выполняются все команды, входящие в блок-1 (ветка «да»), иначе (если условие ложно) выполняются все команды в блоке-2 (ветка «нет») · в неполной форме условного оператора блок-2 пустой (отсутствует); теоретически можно сделать наоборот – так, чтобы блок-1 оказался пустой, но это очень неграмотное решение, поскольку оно осложняет понимание алгоритма, запутывает его · одна команда ветвления может находиться внутри другой, например, так: · на этой схеме блок-10 выполняется, когда a=b; блок-11 – когда a=b=c, блок-12 – когда a=b, но a¹c и, наконец, блок-2 – когда a¹b · на этой схеме (Рисунок 3) одна команда ветвления (с условием «a=c») вложена в другую (с условием «a=b»), каждая из них – это ветвление в полной форме; если блок-12 будет пустой (отсутствует), внутреннее ветвление имеет неполную форму; аналогично, если блок-2 пустой, то внешнее ветвление имеет неполную форму · условный оператор if–else служит для организации ветвления в программе на языке Паскаль · условный оператор может иметь полную или неполную форму; вот фрагменты программы, реализующие ветвления, показанные на рисунках 1 и 2:
здесь вместо комментариев в фигурных скобках (они выделены синим цветом) могут стоять любые операторы языка программирования (в том числе операторы присваивания, другие условные операторы, циклы, вызовы процедур и т.п.)
· обычно при записи программы операторы, находящиеся внутри обоих блоков, сдвигают вправо на 2-3 символа (запись «лесенкой»), это позволяет сразу видеть начало и конец блока (конечно, если «лесенка» сделана правильно) · после else не надо (нельзя!) ставить какое-то условие, эта часть выполняется тогда, когда условие после if неверно (частая ошибка – после else пытаются написать условие, обратное тому, которое стоит после соответствующего ему if) · в Паскале перед else не ставится точка с запятой, поскольку это ключевое слово обозначает не начало нового оператора, а вторую часть условного оператора if–else · слова begin и end (их называют также «операторные скобки») ограничивают блок-1 и блок-2; если внутри блока всего один оператор, эти «скобки» можно не писать, например, допустимы такие операторы
· а вот такие операторы недопустимы
o в первом случае есть begin, но забыли про соответствующий ему end; o во втором фрагменте наоборот, есть end, а begin отсутствует;
o третий случай более сложный: судя по записи «лесенкой», здесь внутри блока-1 находятся 2 оператора, а операторных скобок begin-end нет; в результате получилось, что оператор c:=1 находится внутри блока-1, он выполняется только при условии a=b;
· условный оператор может находиться внутри другого условного оператора, как в блоке-1, так и в блоке-2; например, схема на Рисунке 3 может быть записана на Паскале так:
End Else begin { блок-12 } end; End Else begin { блок-2 } end; |
· ключевая тема этого задания ЕГЭ – использование вложенных условных операторов, причем в тексте задания фрагмент программы обычно записан без отступов «лесенкой» или с неправильными отступами, например, так:
if a = b then begin if a = c then c:=1; end else c:=0; | if a = b then if a = c then c:=1 else c:=0; |
чтобы разобраться с работой этих программ, нужно определить, к какому из условных операторов if относится часть else; для этого используют такое правило: «любой else относится к ближайшему if»
рассмотрим фрагмент слева, в нем перед else стоит end, поэтому для нужно найти соответствующий ему begin; таким образом определяем, что else относится к первому (внешнему) условному оператору
в правом фрагменте перед else нет end, поэтому он относится к ближайшему по тексту внутреннему условному оператору
блок-схемы для двух фрагментов показаны ниже, желтым цветом выделен «переехавший» блок:
· в условных операторах можно использовать сложные условия, которые строятся из простых отношений (<, <=, >, >=, =, <>) с помощью логических операций not («НЕ», отрицание), and («И», одновременное выполнение двух условий) и or («ИЛИ», выполнение хотя бы одного из двух условий)
· в сложном условии сначала выполняются действия в скобках, потом – not, затем – and, затем – or и, наконец, отношения;
операции равного уровня (приоритета) выполняются последовательно слева направо
· поскольку отношения в Паскале имеют низший приоритет, в сложном условии их приходится брать в скобки:
if (a = b) or (b < c) and (c <> d) then begin ... end; |
· в приведенном выше примере сначала определяются результаты сравнения (выражения в скобках), затем выполняется операция and («И»), а затем – or («ИЛИ»)
Пример задания:
Требовалось написать программу, которая вводит с клавиатуры координаты точки на плоскости ( x, y – действительные числа) и определяет принадлежность точки заштрихованной области, включая ее границы. Программист торопился и написал программу неправильно. Вот она:
|
|
var x,y: real;
Begin
readln(x,y);
if y>=x then
if y>=0 then
if y<=2-x*x then
Write('принадлежит')
Else
Write('не принадлежит')
End.
Последовательно выполните следующее:
1. Перерисуйте и заполните таблицу, которая показывает, как работает программа при аргументах, принадлежащих различным областям (A, B, C, D, E, F и G). Точки, лежащие на границах областей, отдельно не рассматривать.
В столбцах условий укажите "да", если условие выполнится, "нет" если условие не выполнится, "—" (прочерк), если условие не будет проверяться, «не изв.», если программа ведет себя по-разному для разных значений, принадлежащих данной области. В столбце "Программа выведет" укажите, что программа выведет на экран. Если программа ничего не выводит, напишите "—" (прочерк). Если для разных значений, принадлежащих области, будут выведены разные тексты, напишите «не изв». В последнем столбце укажите "да" или "нет".
2. Укажите, как нужно доработать программу, чтобы не было случаев ее неправильной работы. (Это можно сделать несколькими способами, поэтому можно указать любой способ доработки исходной программы).
Решение:
1) начнем заполнять таблицу, выписывая истинность каждого из трёх условий
2) условие y>=x истинно выше прямой y=x, то есть в областях A, B, E, F
Область | y>=x? | y>=0? | y<=2-x*x? | вывод | верно? |
A | да | ||||
B | да | ||||
C | нет | ||||
D | нет | ||||
E | да | ||||
F | да | ||||
G | нет |
3) условие y>=0 истинно выше прямой y=0, то есть в областях A, E, G, однако это условие проверяется только тогда, когда первое условие, y>=x, истинно; поэтому для всех областей, где первое условие неверно (это области C, D, G), сразу в столбце второго условия ставим прочерк (условие не будет проверяться)
Область | y>=x? | y>=0? | y<=2-x*x? | вывод | верно? |
A | да | да | |||
B | да | нет | |||
C | нет | – | |||
D | нет | – | |||
E | да | да | |||
F | да | нет | |||
G | нет | – |
4) третье условие выполняется для областей «внутри» параболы, то есть для E, F, G, D; однако оно проверяется только тогда, когда первые два истинны (для А и Е), в остальных строках ставим прочерк:
|
|
Область | y>=x? | y>=0? | y<=2-x*x? | вывод | верно? |
A | да | да | нет | ||
B | да | нет | – | ||
C | нет | – | – | ||
D | нет | – | – | ||
E | да | да | да | ||
F | да | нет | – | ||
G | нет | – | – |
5) как следует из текста программы, она выведет что-то на экран только в том случае, когда выполняются первые два условия и программа выходит на третье: для области А будет выведено «не принадлежит», для области Е – «принадлежит», именно в этих двух случаях программа работает правильно, в остальных – нет:
Область | y>=x? | y>=0? | y<=2-x*x? | вывод | верно? |
A | да | да | нет | не принадлежит | да |
B | да | нет | – | – | нет |
C | нет | – | – | – | нет |
D | нет | – | – | – | нет |
E | да | да | да | принадлежит | да |
F | да | нет | – | – | нет |
G | нет | – | – | – | нет |
6) для того, чтобы доработать программу, проще всего составить одно сложное условие, описывающее всю заштрихованную область
7) в данном случае удобно представить данную область в виде объединения областей, первая из которых включает области E+G, а вторая – области E+F
8) область E+G соответствует условию (y>=0) and (y <=2-x*x)
9) область E+F соответствует условию (y>=x) and (y <=2-x*x)
10) объединение областей выполняется с помощью операции ИЛИ (or), так что полное условие принимает вид
(y>=0) and (y <=2-x*x) or (y>=x) and (y <=2-x*x)
поскольку операция И (and) имеет более высокий приоритет, чем ИЛИ (or), порядок выполнения операций тут правильный; в случае сомнений можно поставить дополнительные скобки:
((y>=0) and (y <=2-x*x)) or ((y>=x) and (y <=2-x*x))
11) поскольку в обоих условиях есть условие y <=2-x*x, запись можно немного сократить:
(y <=2-x*x) and ((y>=x) or (y>=0))
12) доработанная программа выглядит так:
var x,y: real;
Begin
readln(x,y);
if (y <=2-x*x) and ((y>=x) or (y>=0)) then
Write('принадлежит')
Else
Write('не принадлежит')
End.
Ещё пример задания:
Требовалось написать программу, которая вводит с клавиатуры координаты точки на плоскости ( x, y – действительные числа) и определяет принадлежность точки заштрихованной области, включая ее границы. Программист торопился и написал программу неправильно. Вот она:
var x,y: real;
Begin
readln(x,y);
if y <= 1 then
if x >= 0 then
if y >= sin(x) then
Write('принадлежит')
|
|