| Кандидаты должны уметь: | Примечания и рекомендации |
|---|---|
| Реализовать и написать псевдокод по заданному дизайну, представленному в виде блок-схемы программы или структурированного английского языка | |
| Написать псевдокод для: • объявления и инициализации констант • объявления переменных • присвоения значений переменным • выражений, использующих арифметические или логические операторы, ввода с клавиатуры и вывода на экран | |
| Использовать встроенные функции и библиотеки | Любые функции, не указанные в руководстве по псевдокоду, будут предоставлены. Функции обработки строк всегда предоставляются |
Программирование
A-Level Информатика · Тема 11
24:05
Основы программирования
Программа должна запрашивать пароль и продолжать спрашивать, пока не введён правильный. Просто — но какой цикл использовать? Программы принимают решения и повторяют действия, и выбор…
Английское озвучивание · Английский + китайские субтитры (встроенные)
11.1
Основы программирования
Программа
Источник: Программа Cambridge International


От проекта к коду
Вы должны уметь преобразовать проект — блок-схему (блок-схема программы) или структурированный английский — в псевдокод, а затем в реальный язык:
- найти переменные и их типы данных.
- преобразовать блоки ввода/вывода в
INPUT/OUTPUT. - преобразовать ромбы решений в
IF...ELSE...ENDIF(илиCASE). - преобразовать стрелки циклов в
WHILE,REPEAT...UNTILилиFOR. - преобразовать блоки процессов в присваивания или вычисления.
- проверить трассировкой небольшого входного значения.

Константы и переменные
Константа хранит значение, которое никогда не меняется; переменная хранит значение, которое может меняться. Объявляйте их с указанием типа:

CONSTANT Pi = 3.14159
DECLARE Radius : REAL
DECLARE Area : REAL
Radius ← 5
Area ← Pi * Radius * Radius
Используйте константы для повторяющихся фиксированных значений (Pi, MaxScore); это делает код понятнее и легким для изменения в одном месте.
На экзамене константа — это ответ на вопрос «определите более подходящий способ представления» фиксированного значения, такого как ставка налога или максимальный балл, который встречается в нескольких местах псевдокода. Преимущества такой схемы: значение задается один раз и не может быть случайно изменено программой; изменение вносится в одном месте и распространяется на каждое утверждение, использующее его; идентификатор придает значению смысл (MaxScore вместо 100), поэтому код легче читать и проверять; и снижается риск опечатки в длинном значении, таком как 3.14159. Вопрос «назовите значение, которое можно заменить константой» требует дословного текста из псевдокода (0.2, 40), а не нового имени.
Каждая переменная объявляется один раз с идентификатором (ее именем) и типом данных перед использованием. Шесть типов в руководстве по псевдокоду 9618:
| Тип | Хранит | Записывается в коде как | Типичное применение |
|---|---|---|---|
INTEGER |
целые числа | 42, -3 |
счетчик, индекс массива, счетчик цикла |
REAL |
числа с дробной частью | 3.75 |
цена, среднее значение |
CHAR |
один символ | 'A' (одиночные кавычки) |
буква оценки, клавиша меню |
STRING |
последовательность символов | "Hello" (двойные кавычки) |
имя, почтовый индекс |
BOOLEAN |
TRUE или FALSE |
TRUE |
флаг, такой как Found |
DATE |
календарную дату | 12/05/2026 |
дата рождения |
Вопрос "укажите соответствующий тип данных" решается на основе того, как переменная используется в псевдокоде: значение с десятичной точкой является REAL; что-то, установленное в TRUE или FALSE, является BOOLEAN; значение в одинарных кавычках является CHAR; значение, используемое как индекс массива или вместе с DIV и MOD, является INTEGER. Записывайте тип заглавными буквами, так, как он написан в руководстве.
Разобранный пример. Укажите соответствующий тип данных для каждой переменной.
Found ← FALSE
Initial ← 'K'
Price ← 12.99
Count ← Count + 1
Name ← "Li Wei"
Found является BOOLEAN (он хранит FALSE); Initial является CHAR (один символ в одинарных кавычках); Price является REAL (десятичное значение); Count является INTEGER (счетчик, увеличивающийся на единицу); Name является STRING (текст в двойных кавычках).
Присваивание и выражения
Используйте ← для присваивания:
Total ← Total + 1
Average ← Sum / Count
Выражения используют операторы:
- арифметические
+ - * /, плюсDIV(целочисленное деление) иMOD(остаток):7 DIV 2 = 3;7 MOD 2 = 1. - сравнения
=,<>,<,>,<=,>=. - логические
AND,OR,NOT.
Приоритет (от высшего к низшему): NOT → * / DIV MOD → + - → сравнения → AND → OR. Используйте скобки, если не уверены.
Ввод и вывод
OUTPUT "Enter your name:"
INPUT Name
OUTPUT "Hello, ", Name
Встроенные функции и библиотеки
Многие задачи имеют готовые библиотечные подпрограммы, поэтому их не нужно писать. В вставке к Бумаге 2 перечислены те, которые можно использовать, с их точными именами, параметрами и типами возвращаемых значений; любая другая функция, необходимая задаче, дается в самой задаче. Имена ниже — это имена из вставки. VAL и STR — это имена IGCSE и не встречаются ни в одном документе 9618, поэтому они не дают баллов. UCASE и LCASE — другой случай: они являются частью 9618, определены в Руководстве по псевдокоду, но принимают один CHAR, а вставка их вообще не перечисляет — для целой строки в Бумаге 2 используется подпрограмма TO_UPPER.
Библиотека программ содержит подпрограммы, которые уже написаны, скомпилированы и протестированы; программа обращается к ним вместо того, чтобы писать собственные. Преимущества, которые принимает экзаменационная схема для вопроса о «трех преимуществах»: подпрограммы уже протестированы, поэтому менее склонны содержать ошибки; они экономят время разработки; они могут выполнять то, что не мог бы написать программист (сложная статистика, графика); они написаны экспертами и переиспользуются во многих программах; и подпрограмму с фиксированным интерфейсом можно вызвать из любого места программы.
| Подпрограмма | Возвращает | Пример |
|---|---|---|
LENGTH(s) |
количество символов в s |
LENGTH("Hello") = 5 |
LEFT(s, n) / RIGHT(s, n) |
первые / последние n символов |
RIGHT("Hello", 2) = "lo" |
MID(s, start, n) |
n символов начиная с позиции start (позиции нумеруются с 1) |
MID("Hello", 2, 3) = "ell" |
TO_UPPER(s) / TO_LOWER(s) |
s заглавными буквами / строчными буквами |
TO_UPPER("ab1") = "AB1" |
NUM_TO_STR(x) / STR_TO_NUM(s) |
число как строка / строка как число | STR_TO_NUM("3.5") = 3.5 |
IS_NUM(s) |
TRUE если s — допустимое число |
IS_NUM("12a") = FALSE |
ASC(c) / CHR(n) |
кодовое значение символа c / символ с кодом n |
ASC('A') = 65, CHR(66) = 'B' |
INT(x) |
целую часть от x |
INT(7.9) = 7 |
RAND(n) |
случайное вещественное число от 0 включительно до, но не включая, n |
INT(RAND(6)) + 1 — бросок игральной кости |
DAY(d), MONTH(d), YEAR(d) |
части от DATE |
YEAR(TODAY()) |
DAYINDEX(d), SETDATE(d, m, y), TODAY() |
день недели (1 = воскресенье); дата, составленная из трех целых чисел; сегодняшняя дата | |
EOF(f) |
TRUE когда файл f больше не имеет строк для чтения |
WHILE NOT EOF("data.txt") |
Строки объединяются с помощью & (конкатенация): результат "A" & "BC" равен "ABC". Используйте точные имена из вставки, сохраняя порядок параметров.
Даты и случайные числа часто используются в виде однострочных выражений. SETDATE(17, 11, 2007) создает дату 17 ноября 2007 года; 12 - MONTH(MyDOB) — количество месяцев от месяца рождения до конца года; IF DAYINDEX(MyDOB) = 5 THEN проверяет четверг, так как воскресенье — это день 1. RAND(n) возвращает вещественное число от 0 включительно до, но не включая, n, поэтому случайное целое число от Low до High включительно вычисляется как INT(RAND(High - Low + 1)) + Low: INT(RAND(21)) - 10 дает значение от -10 до 10.

s = "COMPUTER" (позиции 1–8)Разбор примера. Вычислите каждое выражение, зная, что Word ← "Program", Code ← 'Q' и N ← 7.
| Выражение | Значение | Причина |
|---|---|---|
LENGTH(Word) |
7 |
семь символов |
MID(Word, 4, 2) |
"gr" |
два символа, начиная с позиции 4 |
LEFT(Word, 3) & "!" |
"Pro!" |
объединено со строкой & |
TO_UPPER(RIGHT(Word, 2)) |
"AM" |
внутренняя функция выполняется первой |
ASC(Code) - ASC('A') |
16 |
'Q' равно 81, а 'A' равно 65 |
N DIV 2 + N MOD 2 |
4 |
3 + 1 |
NUM_TO_STR(N) & "th" |
"7th" |
число сначала преобразуется в строку |
INT(N / 2) |
3 |
3.5 обрезано до своей целой части |
Вычисляйте изнутри наружу и сохраняйте кавычки: "7" — это строка, а 7 — число.
Разбор примера. Каждое утверждение может содержать ошибку в использовании функции или оператора. Опишите ошибку или напишите NO ERROR. (Предполагается, что все переменные имеют правильный тип.)
| Утверждение | Ошибка |
|---|---|
Result ← 2 & 4 |
& соединяет строки; 2 и 4 являются целыми числами, поэтому требуется + |
SubString ← MID("pseudocode", 4, 1) |
NO ERROR: один символ с позиции 4, "u" |
IF x = 3 OR 4 THEN |
OR требует логического значения с каждой стороны: IF x = 3 OR x = 4 THEN |
Result ← Status AND INT(x / 2) |
AND требует двух логических значений; INT(x / 2) — целое число |
Message ← "Done" + LENGTH(MyString) |
+ не может прибавить строку к целому числу: "Done" & NUM_TO_STR(LENGTH(MyString)) |
Каждый оператор работает с определенными типами: & со строками, + - * / DIV MOD с числами, AND OR NOT с булевыми значениями, а = <> требует два значения одного и того же типа. Таблица «вычислите каждое выражение или напишите ERROR» отмечается аналогично: значения LENGTH(42) и "A" + 1 являются ERROR, поскольку тип не соответствует функции или оператору.
Разбор примера. Используя Points ← 100, Active ← TRUE и Exempt ← FALSE, вычислите каждое выражение.
| Выражение | Значение | Причина |
|---|---|---|
(Points > 99) OR Active |
TRUE |
обе стороны истинны; достаточно одной |
(Points MOD 2 = 0) OR Exempt |
TRUE |
100 MOD 2 равно 0 |
(Points <= 75) AND (Active OR Exempt) |
FALSE |
первая сторона ложна, а AND требует оба значения |
(Active OR NOT Active) AND NOT Exempt |
TRUE |
Active OR NOT Active всегда истинно |
Последнее выражение упрощается: X OR NOT X равно TRUE при любом значении X, поэтому все выражение сводится просто к NOT Exempt. Сначала вычислите скобки, затем NOT, потом AND, и наконец OR.
Переменная — это помеченная коробка
Каждое присваивание хранит одно значение в именованной коробке; повторное присвоение того же имени перезаписывает его. Пройдите по программе и следите за тем, как каждая коробка принимает свое текущее значение.
| English | Русский |
|---|---|
| pseudocode/ˈsuːdəʊkəʊd/ | псевдокод |
| variables/ˈveərɪəblz/ | переменных |
| data types/ˈdeɪtə taɪps/ | типы данных |
| assignment/əˈsaɪnmənt/ | присваиванием |
| constant/ˈkɒnstənt/ | постоянно |
| identifier/aɪˈdentɪfaɪə/ | идентификатор |
| function/ˈfʌŋkʃn/ | функцией |
| library routines/ˈlaɪbrəri ruːˈtiːnz/ | библиотечные процедуры |
| insert/ˈɪnsɜːt/ | insert |
| parameters/pəˈræmɪtəz/ | параметрами |
| program library/ˈprəʊɡræm ˈlaɪbrəri/ | библиотека программ |
| concatenation/kənˌkætəˈneɪʃn/ | конкатенацией |
11.2
Выбор
Программа
| Кандидаты должны уметь: | Примечания и рекомендации |
|---|---|
| Использовать псевдокод для написания: • оператора ‘IF’ с блоком ‘ELSE’ и вложенными операторами IF • структуры ‘CASE’ • цикла с управляющим счетчиком: • цикла с постусловием • цикла с предусловием | |
| Обосновать, почему одна структура цикла может быть более подходящей для решения задачи, чем другие |
Источник: Программа Cambridge International
Выбор определяет, какие шаги будут выполнены.
IF age >= 18 THEN
OUTPUT "Adult"
ELSE
OUTPUT "Minor"
ENDIF

Для более чем двух случаев можно использовать вложенный IF, но глубокое вложение трудно читать — конструкция CASE чище при проверке одного значения против нескольких вариантов:
CASE OF Grade
"A": OUTPUT "Excellent"
"B": OUTPUT "Good"
OTHERWISE: OUTPUT "Try again"
ENDCASE
Cambridge CASE позволяет использовать одиночные значения, списки значений (1, 2, 3:) и диапазоны (1 TO 5:).
Вложенный IF — это конструкция IF внутри ветки другого IF. Каждая IF требует собственной ENDIF, и экзаменатор проверяет, что каждая конструкция завершена:
IF Mark >= 50 THEN
IF Mark >= 80 THEN
OUTPUT "Distinction"
ELSE
OUTPUT "Pass"
ENDIF
ELSE
OUTPUT "Fail"
ENDIF
Границы — это места, где теряются баллы. Условие «Оценка 50 или выше означает успех» является Mark >= 50, а не Mark > 50; последняя CASE ветка для «всего остального» записывается как OTHERWISE, а не условие вроде > 200. Неправильное сравнение здесь — это логическая ошибка: программа работает, но выдает неверный результат для некоторых входных данных — и таблица трассировки со граничным значением, таким как 50, помогает её найти.

Разобранное решение. Перепишите это с той же функциональностью, не используя структуру CASE.
CASE OF MySwitch
1: ThisChar ← 'a'
2: ThisChar ← 'y'
3: ThisChar ← '7'
OTHERWISE: ThisChar ← '*'
ENDCASE
Каждое значение становится веткой цепочки IF, а OTHERWISE становится последней ELSE:
IF MySwitch = 1 THEN
ThisChar ← 'a'
ELSE
IF MySwitch = 2 THEN
ThisChar ← 'y'
ELSE
IF MySwitch = 3 THEN
ThisChar ← '7'
ELSE
ThisChar ← '*'
ENDIF
ENDIF
ENDIF
Два присваивания одному и тому же значению объединяются в один блок с перечислением значений: 1, 2: ThisChar ← 'a'. Охранительные условия проверяются в порядке: при наличии диапазонов, таких как 1 TO 50:, за которым следует 40 TO 60:, значение 45 попадет в первое подходящее ветвление, поэтому присваивание в последующем блоке может быть никогда не выполнено — а если предыдущие блоки уже охватывают все возможные значения, то ветвление OTHERWISE также никогда не будет достигнуто.
В обратном направлении, вложенные IF, проверяющие несколько булевых переменных, становятся понятнее, если на каждый исход использовать одно условие: IF A AND B AND C THEN CALL Sub1(), затем IF A AND B AND NOT C THEN CALL Sub2() и так далее. Объединение проверок с помощью AND и OR устраняет вложенность, а IF A THEN принимается вместо IF A = TRUE THEN.
Выбор (IF / ELSE)
Измените ввод и посмотрите, какая ветвь выполнится — суть выбора.
| English | Русский |
|---|---|
| flowchart/ˈfləʊtʃɑːt/ | блок-схема |
| structured English/ˈstrʌktʃəd ˈɪŋɡlɪʃ/ | структурированный английский |
11.2
Итерация
Итерация повторяет блок. Три вида циклов различаются количеством повторений тела.
Цикл с управляющим счетчиком (FOR)
Цикл с управляющим счетчиком — используйте его, когда заранее знаете, сколько раз нужно повторить:
FOR i ← 1 TO 10
OUTPUT i
NEXT i
Конструкция STEP может изменять счетчик (например, FOR i ← 10 TO 1 STEP -1). Лучше всего подходит для фиксированного числа повторений или обработки каждого элемента массива.
Цикл с предварительным условием (WHILE)
Цикл с предварительным условием проверяет условие перед каждой итерацией, поэтому он может выполниться ноль раз:
WHILE total < 100 DO
INPUT n
total ← total + n
ENDWHILE
Цикл с постусловием (REPEAT...UNTIL)
Цикл с постусловием проверяет условие после каждой итерации, поэтому он всегда выполняется как минимум один раз:
REPEAT
INPUT password
UNTIL password = correctPassword
Выбор подходящего цикла

- счетчик известен заранее → FOR.
- возможно нулевое количество итераций → WHILE.
- обязательно хотя бы одна итерация → REPEAT...UNTIL.
Обоснуйте выбор тем, известен ли счетчик и должно ли тело выполниться хотя бы один раз. Типичный вопрос предлагает сценарий («спросите пароль до тех пор, пока он не будет введен верно, но спрашивайте как минимум один раз») и спрашивает, какой цикл подходит.
Два балла начисляются за название цикла и причину, словами схемы оценивания: с управляющим счетчиком, потому что число итераций известно до начала цикла; с постусловием, потому что тело цикла должно выполниться хотя бы один раз; с предварительным условием, потому что цикл может вообще не потребоваться. Цикл по четырем элементам массива, который был записан как WHILE со счетчиком, «не является наиболее подходящим»: счетчик, равный четырем, известен, поэтому подходит цикл FOR.
Разобранное решение. Какой цикл подходит для каждой задачи? (a) распечатать таблицу умножения на 12; (b) продолжать читать числа, пока пользователь не введет 0; (c) запрашивать пароль до тех пор, пока он не будет введен верно. Выбирайте, задавая вопросы о количестве итераций и о том, когда происходит проверка. (a) Счетчик известен заранее (12), поэтому используйте цикл FOR. (b) Счетчик неизвестен, и первый ввод может уже быть 0 — значит, проверка должна стоять до тела: цикл WHILE, который выполняется ноль или больше раз. (c) Счетчик неизвестен, но вы должны спросить хотя бы один раз, прежде чем появится что-то для проверки — значит, проверка стоит после тела: цикл REPEAT...UNTIL, который выполняется один или больше раз. Решающий вопрос: должно ли тело выполниться хотя бы один раз? WHILE может выполниться ноль раз, REPEAT всегда выполняется один раз.
Прогон без выполнения (dry run) с таблицей трассировки
Таблица трассировки фиксирует значение каждой переменной во время прогона без выполнения (ручного прохождения алгоритма). Это способ протестировать цикл на бумаге, и задание на шесть баллов в большинстве Paper 2.
DECLARE Count, Total : INTEGER
Count ← 1
Total ← 0
WHILE Total < 10
Total ← Total + Count * 2
Count ← Count + 1
ENDWHILE
OUTPUT Count, Total
| Count | Total | Total < 10 | OUTPUT |
|---|---|---|---|
| 1 | 0 | TRUE | |
| 2 | 2 | TRUE | |
| 3 | 6 | TRUE | |
| 4 | 12 | FALSE | 4, 12 |
Правила, за которые ставятся баллы: один столбец на переменную, в порядке, указанном в задании; пишите значение только тогда, когда оно изменяется; начинайте новую строку каждый раз, когда цикл повторяется; вычисляйте условие с текущими значениями и останавливайтесь, как только оно станет FALSE; выводите результат в отдельном столбце точно так, как он выглядел бы. Трассируйте алгоритм именно так, как он написан, а не так, как вы думаете, что он должен был быть написан — если он никогда не останавливается, напишите об этом.
Разобранное решение. Какие конструкции использует каждая строка — selection (выбор), iteration (итерация) или вызов подпрограммы?
| Pseudocode | Selection | Iteration | Subroutine |
|---|---|---|---|
| IF Ready = TRUE THEN |
CALL Start()
ENDIF
| FOR I ← 1 TO 20 ... NEXT I | | yes | |
| WHILE NOT IsFull() ... ENDWHILE | | yes | yes |
| CASE OF Key ... OTHERWISE ... ENDCASE | yes | | |
IF и CASE — это выбор; FOR, WHILE и REPEAT — это итерация; имя, за которым следуют скобки — Start(), IsFull(), — это вызов процедуры или функции, где бы он ни появлялся, включая условия.
Отследите цикл, проход за проходом
Таблица трассировки фиксирует каждую переменную после каждого прохода цикла. Следите за тем, как счетчик i растет, пока накапливается текущая сумма — именно это требуется заполнить в вопросе по трассировке на экзамене.
Отслеживание цикла
Шагайте по циклу и наблюдайте, как меняются переменные при каждом проходе — именно это фиксирует таблица отслеживания.
| English | Русский |
|---|---|
| selection/sɪˈlekʃn/ | выбор |
| nested/ˈnestɪd/ | вложенный |
| logic error/ˈlɒdʒɪk ˈerə/ | логическая ошибка |
| trace table/treɪs ˈteɪbl/ | трассировочная таблица |
| iteration/ˌɪtəˈreɪʃn/ | итерации |
| count-controlled loop/kaʊnt kənˈtrəʊld luːp/ | цикл с числовым управлением |
| pre-condition loop/priː kənˈdɪʃn luːp/ | цикл с предварительным условием |
| post-condition loop/pəʊst kənˈdɪʃn luːp/ | цикл с последующим условием |
| dry run/draɪ rʌn/ | сухой прогон |
11.3
Процедуры и функции
Программа
| Кандидаты должны уметь: | Примечания и рекомендации |
|---|---|
| Определить и использовать процедуру | |
| Объяснить, где при построении алгоритма уместно использовать процедуру | |
| Использовать параметры | Процедура может иметь ноль, один или несколько параметров. Параметр может передаваться по ссылке или по значению |
| Определить и использовать функцию | |
| Объясните, где в процессе построения алгоритма уместно использовать функцию | Функция используется в выражении, например, возвращаемое значение заменяет вызов функции |
| Использовать терминологию, связанную с процедурами и функциями | включая заголовок процедуры/функции, интерфейс процедуры/функции, параметр, аргумент, возвращаемое значение |
| Писать эффективный псевдокод |
Источник: Программа Cambridge International
Структурное программирование строит программу из небольших именованных подпрограмм, каждая из которых выполняет одну задачу.
Процедура
Процедура — это именованный блок, который выполняет действие; она может принимать параметры, но не возвращает значение.
PROCEDURE Greet(name : STRING)
OUTPUT "Hello, ", name
ENDPROCEDURE
CALL Greet("Ada")
Функция
Функция похожа на процедуру, но она возвращает значение, которое становится частью выражения.
FUNCTION Square(x : INTEGER) RETURNS INTEGER
RETURN x * x
ENDFUNCTION
result ← Square(5) + 1 // result = 26
Используйте процедуру, когда подпрограмма выполняет действие; используйте функцию, когда она вычисляет значение для вызывающего кода.
Спецификация экзамена спрашивает, где в построении алгоритма уместно применение каждой из них. Процедура уместна там, где одна и та же группа шагов требуется в нескольких местах (валидация ввода, вывод меню, обмен двумя значениями): шаги записываются один раз и CALLаются по имени. Функция уместна там, где необходимо вычислить одно значение, а затем использовать его в выражении — сумму, результат деления/умножения на TRUE/FALSE, наибольшее из двух чисел, — поскольку возвращаемое значение заменяет вызов: IF IsValid(Code) THEN.

Параметры
Параметр — это переменная, которую подпрограмма объявляет для получения входных данных; значения, которые предоставляет вызывающий код, называются аргументами. Два способа передачи:
- передача по значению — подпрограмма получает копию; изменения внутри нее не влияют на вызывающий код. Используйте для входных данных, которые только читаются.
- передача по ссылке — подпрограмма получает ссылку на переменную вызывающего кода; изменения влияют на вызывающий код. Используйте, когда необходимо обновить параметр.

PROCEDURE Swap(BYREF a : INTEGER, BYREF b : INTEGER)
DECLARE temp : INTEGER
temp ← a
a ← b
b ← temp
ENDPROCEDURE
В псевдокоде Кембриджа тип параметра указывается в заголовке, BYVAL или BYREF, перед каждым параметром. Если ни один из них не указан, по умолчанию предполагается BYVAL. Следовательно,dirname, который должен изменить переменную вызывающей программы — например, Swap, или процедура, обновляющая накопленную сумму, — требует указания BYREF в своем заголовке.
Разобранный пример. Что будет выведено?
PROCEDURE Adjust(BYREF X : INTEGER, BYVAL Y : INTEGER)
X ← X + Y
Y ← Y * 2
ENDPROCEDURE
A ← 5
B ← 3
CALL Adjust(A, B)
OUTPUT A, B
X является ссылкой на A, поэтому A становится равно 8. Y представляет собой копию B, поэтому удвоение Y оставляет B равным 3. Выводом будет 8, 3. Если бы в заголовке было указано BYVAL X, значение A всё равно осталось бы равным 5.
Локальные и глобальные переменные
Локальная переменная объявляется внутри подпрограммы и существует только во время ее выполнения. Глобальная переменная объявляется вне подпрограммы и доступна повсюду. Предпочтайте локальные переменные и параметры — активное использование глобальных переменных затрудняет понимание и тестирование кода. (Область видимости имени называется его областью действия.)
Однострочное отличие: глобальную переменную можно использовать из любой части программы, локальную — только внутри подпрограммы, где она объявлена. Преимущества локальных переменных, принимаемые схемой экзамена: тот же идентификатор можно использовать в другой подпрограмме без коллизий; значение нельзя случайно изменить другими частями программы; память освобождается при завершении подпрограммы; и подпрограмма является самодостаточной, поэтому ее можно протестировать отдельно и использовать в другой программе.
Локальная переменная создается каждый раз при вызове подпрограммы и уничтожается при ее завершении, поэтому она не может сохранять значение от одного вызова к другому. Поэтому процедуре, накапливающей строку при повторных вызовах, необходимо, чтобы эта строка была глобальной (или передавалась BYREF). Если MyString меняется с глобальной на локальную, объявленную внутри MyOutput(), каждый вызов начинается с новой пустой MyString, текст, добавленный предыдущими вызовами, теряется, и процедура «работает не так, как ожидается».


Когда использовать подпрограмму
Используйте подпрограмму, когда:
- одна и та же логика встречается в нескольких местах — запишите ее один раз, вызывайте много раз.
- блок имеет ясную именованную цель — имя документирует, что он делает.
- программа сложна — разбейте ее на части (декомпозиция).
- вы хотите протестировать фрагмент изолированно.
Не делайте их настолько мелкими, чтобы стоимость вызова превышала работу внутри.
Терминология
- определение — блок ⟨
PROCEDURE ... ENDPROCEDURE⟩ (или функции). - вызов — место, где он invoked. аргумент — значение, передаваемое внутрь. параметр — переменная, которая его принимает.
- возвращаемое значение — то, что функция возвращает обратно.
- заголовок процедуры/функции — первая строка, дающая имя и параметры (
PROCEDURE Name(params)илиFUNCTION Name(params) RETURNS type). - интерфейс/подпись процедуры/функции — имя + параметры + тип возвращаемого значения: то, что должен знать вызывающий код для использования её.
Разобранное решение. Опишите каждый термин, используемый в заголовке FUNCTION Pass2(Count : INTEGER) RETURNS BOOLEAN.
| Термин | Значение |
|---|---|
FUNCTION |
подпрограмма, возвращающая значение |
Pass2 |
идентификатор, используемый для её вызова |
Count |
параметр: идентификатор, принимающий переданный аргумент |
INTEGER |
тип данных параметра |
RETURNS BOOLEAN |
тип данных значения, которое возвращает функция |
Два идентификатора в PROCEDURE MyProc(Count : INTEGER, Message : STRING) являются параметрами: они принимают значения, передаваемые при вызове процедуры, и используются внутри неё как локальные переменные.
Чтобы преобразовать процедуру в функцию: замените PROCEDURE на FUNCTION и добавьте RETURNS <type>; замените OUTPUT (или параметр BYREF, передающий результат наружу) на оператор присваивания RETURN; и измените каждый вызов, чтобы возвращаемое значение использовалось, например, Result ← Unpack(Text) вместо CALL Unpack(Text, Result). Для вопроса «напишите заголовок» запишите всю строку целиком: FUNCTION Calculate(Expression : STRING) RETURNS INTEGER. Параметр массива передается по ссылке, поэтому процедура, записывающая данные в массив, изменяет массив вызывающей программы.
Когда программа получает новый модуль, интерфейс — это первое, о чем договариваются: имя, параметры (сколько, в каком порядке, какого типа) и тип возвращаемого значения, а также любые глобальные данные, которые модуль читает или записывает. Модулю, отправляющему напоминание до дедлайна, нужен запись (или его индекс) в качестве параметра и он ничего не возвращает, поэтому это процедура; основная программа вызывает её один раз для каждой записи.
Написание модуля для Билета 2
Половина Билета 2 — это «напишите псевдокод для модуля X». Экзаменационная схема начисляет балл за каждую деталь, поэтому даже незавершенный модуль получит баллы за каждую правильную часть. Части, на которые смотрит экзаменатор:

- Заголовок, как описано в задании:
PROCEDURE Name(Param : TYPE)илиFUNCTION Name(Param : TYPE) RETURNS TYPE, с указаниемBYREFтам, гдеdirname должна изменить аргумент. - Локальные объявления: для каждой локальной переменной укажите её тип
DECLARE, а также инициализируйте счетчики и суммы (Count ← 0). - Цикл, проходящий по каждому элементу: для массива, размер которого известен, используйте
FOR Index ← 1 TO 50; для файла —WHILE NOT EOF(...). - Условие, содержащее правильную операцию сравнения и границу, примененное к нужному элементу:
IF Score[Index] > Limit THEN. - Обновление внутри ветки: увеличение счетчика, сохранение значения или вывод сообщения.
- Завершение: запись
RETURNодин раз после цикла, в функции; операторыENDFUNCTIONилиENDPROCEDURE; а также закрытие каждогоIF,FORиWHILE.
Разобранное решение. Глобальный массив Score : ARRAY[1:50] OF INTEGER хранит оценки. Напишите функцию CountAbove(Limit : INTEGER), которая возвращает количество оценок, больших Limit.
FUNCTION CountAbove(BYVAL Limit : INTEGER) RETURNS INTEGER
DECLARE Index, Count : INTEGER
Count ← 0
FOR Index ← 1 TO 50
IF Score[Index] > Limit THEN
Count ← Count + 1
ENDIF
NEXT Index
RETURN Count
ENDFUNCTION
Баллы: заголовок с его параметром и RETURNS INTEGER; объявление переменной Count и присвоение ей значения 0; цикл по всем элементам 50; сравнение > Limit (не >=); обновление счетчика внутри блока IF; вывод результата RETURN Count после цикла. Основная программа использует возвращаемое значение в выражении или выводе: например, OUTPUT "Above 70: ", CountAbove(70).
Разобранное решение. Напишите функцию IsValid(Code : STRING), которая возвращает TRUE, когда Code представляет собой две заглавные буквы, за которыми следуют четыре цифры — формат AB1234 — и FALSE в противном случае.
FUNCTION IsValid(BYVAL Code : STRING) RETURNS BOOLEAN
DECLARE Index : INTEGER
DECLARE Ch : STRING
IF LENGTH(Code) <> 6 THEN
RETURN FALSE
ENDIF
FOR Index ← 1 TO 6
Ch ← MID(Code, Index, 1)
IF Index <= 2 THEN
IF Ch < "A" OR Ch > "Z" THEN
RETURN FALSE
ENDIF
ELSE
IF Ch < "0" OR Ch > "9" THEN
RETURN FALSE
ENDIF
ENDIF
NEXT Index
RETURN TRUE
ENDFUNCTION
Проверка длины выполняется первой, поэтому запрос позиции MID никогда не будет сделан для несуществующего индекса. Валидация такого рода возвращает булево значение BOOLEAN, чтобы вызывающая программа могла вывести сообщение IF IsValid(Entry) THEN ... ELSE OUTPUT "Invalid code" ENDIF: сообщение пользователю выводит вызывающая программа, а не функция — функция вычисляет, процедура выполняет действия.
Разобранное решение. Напишите функцию IsPalindrome(Word : STRING), которая возвращает TRUE, когда Word читается одинаково в прямом и обратном направлении, например, "RACECAR".
Сравнивайте символы с двух концов, двигаясь внутрь: позиция Index сопоставляется с позицией Len - Index + 1, и достаточно проверять только первую половину.

i сопоставляется с позицией Len - i + 1, проверка прекращается в серединеFUNCTION IsPalindrome(BYVAL Word : STRING) RETURNS BOOLEAN
DECLARE Len, Index : INTEGER
Len ← LENGTH(Word)
FOR Index ← 1 TO Len DIV 2
IF MID(Word, Index, 1) <> MID(Word, Len - Index + 1, 1) THEN
RETURN FALSE
ENDIF
NEXT Index
RETURN TRUE
ENDFUNCTION
Те же три инструмента — цикл FOR по позициям, чтение одного символа через MID(s, i, 1) и сборка новой строки через & — решают большинство модулей со строками в Бумаге 2: подсчет частоты встречаемости символа (IF MID(s, i, 1) = Ch THEN Count ← Count + 1), замена каждого вхождения символа (добавление либо NewChar, либо оригинального символа к NewString на каждой позиции), скрытие всех цифр номера карты, кроме последних четырех (добавление '*' для каждой позиции до ⟨⟩ Len - 4) или создание собственной функции MID() путем объединения символов из диапазона ⟨⟩ Start до ⟨⟩ Start + Length - 1. Запрос позиции за пределами строки с помощью MID вызывает ошибку времени выполнения, поэтому сначала проверяйте ⟨⟩ LENGTH.
Файлы. Значения в переменных исчезают при завершении программы, поэтому модуль, который должен сохранять данные для следующего запуска, записывает их в файл: открытие файла OPENFILE "scores.txt" FOR WRITE, одна запись ⟨⟩ WRITEFILE "scores.txt", NUM_TO_STR(Score[Index]) за строку внутри цикла и закрытие файла CLOSEFILE "scores.txt" один раз после цикла; чтение обратно использует FOR READ, READFILE и WHILE NOT EOF("scores.txt"). Тема 10 содержит полный раздел о файлах; здесь баллы начисляются за правильное открытие режима, чтение или запись внутри цикла и закрытие один раз после него.
Стек вызовов: push при вызове, pop при возврате
Вызов подпрограммы помещает новый кадр на вершину стека; возврат из неё удаляет этот кадр и возвращает значение вызывающему коду. Вызываемая функция всегда соответствует кадру на вершине стека.
| English | Русский |
|---|---|
| array/əˈreɪ/ | массив (array) |
| operators/ˈɒpəreɪtəz/ | операторы |
| precedence/ˈpresɪdəns/ | приоритет |
| procedure/prəˈsiːdʒə/ | процедура |
| structured programming/ˈstrʌktʃəd ˈprəʊɡræmɪŋ/ | структурное программирование |
| subroutines/ˈsʌbruːtiːnz/ | подпрограммы |
| return value/rɪˈtɜːn ˈvæljuː/ | возвращаемого значения |
| arguments/ˈɑːɡjuːmənts/ | аргументы |
| pass by value/pæs baɪ ˈvæljuː/ | передача по значению |
| pass by reference/pæs baɪ ˈrefrəns/ | передача по ссылке |
| global variable/ˈɡləʊbl ˈveərɪəbl/ | глобальная переменная |
| local variable/ˈləʊkl ˈveərɪəbl/ | локальная переменная |
| scope/skəʊp/ | область применения |
| decomposition/ˌdiːkɒmpəˈzɪʃn/ | разложение |
| signature/ˈsɪɡnɪtʃə/ | подпись |
| format/ˈfɔːmæt/ | формат |
| Validation/ˌvælɪˈdeɪʃn/ | Валидация |
| run-time error/rʌn taɪm ˈerə/ | ошибка во время выполнения |
| invariant/ɪnˈveərɪənt/ | инвариантный |
| linear search/ˈlɪnɪə sɜːtʃ/ | линейный поиск |
| syntax error/ˈsɪntæks ˈerə/ | синтаксическая ошибка |
11.3
Написание эффективного псевдокода
Три характеристики, которые делают псевдокод более понятным — ответ на вопрос «назовите три характеристики» — это осмысленные имена (Total, а не t), отступы операторов внутри каждого блока и комментарии (// ...), объясняющие назначение; также принимаются ключевые слова заглавными буквами, один оператор на строку и пустые строки между секциями. Эффективный псевдокод делает следующее:
- вынести инварианты из циклов — если значение (инвариант) не изменяется при изменении счетчика цикла, вычислите его один раз перед циклом.
- рано выйти из цикла, когда ответ найден (прекратить линейный поиск сразу после появления целевого элемента).
- избегать избыточных вычислений — сохранить результат и использовать его повторно вместо повторного вычисления.
- выбрать правильную структуру данных — массив предпочтительнее множества отдельных переменных, когда элементы относятся к одному набору.
- заменить глубокие вложенные IF на CASE при проверке одного значения на соответствие множеству условий.
- комментировать намерение, а не механику (
// validate the postcode, а не// loop 6 times). - использовать осмысленные имена (
numberOfPupils, а неn) и инициализировать переменные до их использования.

11.3
Тестирование и ошибки
Три вида ошибок, каждый из которых обнаруживается особым образом:
| Ошибка | Суть | Пример | Как обнаруживается |
|---|---|---|---|
| синтаксическая ошибка | нарушение правил языка | пропущена запятая ENDIF; неправильная синтаксическая конструкция OUTPT "Hi" |
компилятор/переводчик, до запуска программы |
| ошибка времени выполнения | программа работает, но оператор не может быть выполнен | деление на ноль; индекс массива 0 или 51; вызов функции с некорректным параметром; цикл, который никогда не заканчивается, из-за чего программа «зависает» | во время выполнения: программа останавливается или зависает |
| логическая ошибка | программа выполняется до конца, но вывод неверен | > там, где требовалось бы ⟨⟩ >=; сумма никогда не устанавливалась в ⟨⟩ 0 |
тестирование с использованием таблицы проследования и выбранных тестовых данных |
IDE помогает найти последние два вида: точка останова останавливает программу на выбранной строке; пошаговое выполнение выполняет операторы по одному; а окно отчета (или наблюдения) показывает значение каждой переменной в этот момент, позволяя увидеть строку, где значение становится неверным. Методы тестирования и тестовые данные рассматриваются в теме 12.
| English | Русский |
|---|---|
| IDE/ˌaɪ diː ˈiː/ | Среда разработки (IDE) |
| breakpoint/ˈbreɪkpɔɪnt/ | точка останова |
| single stepping/ˈsɪŋɡl ˈstepɪŋ/ | построчное выполнение |
11.3
Определения, принимаемые экзаменатором
Вопросы с определениями оцениваются по фиксированной формулировке. Выучите их точно.
| Термин | Определение |
|---|---|
| процедура | подпрограмма, выполняющая задачу (последовательность шагов) и не возвращающая значение; вызывается с помощью CALL |
| функция | подпрограмма, возвращающая одно значение в точку вызова, поэтому её можно использовать в выражении |
| параметр | идентификатор в заголовке подпрограммы, получающий значение или ссылку при вызове подпрограммы |
| аргумент | значение (или переменная), передаваемое при вызове, соответствующее параметру |
| передача по значению | копии значения аргумента передаются подпрограмме, поэтому изменения внутри неё не влияют на исходную переменную |
| передача по ссылке | адрес переменной передается подпрограмме, поэтому изменения внутри неё изменяют исходную переменную |
| заголовок | первая строка определения подпрограммы: её имя, параметры и, для функции, тип возвращаемого значения |
| интерфейс | то, что должна знать вызывающая программа для использования подпрограммы: её имя, параметры (количество, порядок, тип) и тип возвращаемого значения |
| возвращаемое значение | значение, которое функция возвращает обратно в выражение, которое её вызвало |
| локальная переменная | объявленная внутри подпрограммы; существует только во время работы подпрограммы и может использоваться только внутри неё |
| глобальная переменная | объявленная вне всех подпрограмм; может использоваться в любом месте программы |
| цикл с управляемым количеством итераций | повторяется фиксированное число раз, управляется счетчиком (FOR ... NEXT) |
| цикл с предварительной проверкой условия | проверяет условие перед каждой итерацией, поэтому тело может не выполниться ни разу (WHILE ... ENDWHILE) |
| цикл с последующей проверкой условия | проверяет условие после каждой итерации, поэтому тело выполняется как минимум один раз (REPEAT ... UNTIL) |
| константа | именованное значение, которое не может измениться во время выполнения программы |
| подпрограмма | автономный блок кода, выполняющий задачу и вызываемый по имени: процедура или функция |
| библиотека процедур | подпрограмма, уже написанная и протестированная, доступная для вызова из программы |
11.3
Советы для экзамена
- Различайте процедуру (без возвращаемого значения) и функцию (возвращающую значение); знайте передачу по значению против передачи по ссылке.
- Выберите правильный цикл: управляемый количеством (FOR), когда количество повторений известно, управляемый условием (WHILE/REPEAT) в противном случае.
- Различайте локальные и глобальные переменные и область видимости; предпочитайте локальные переменные в перенастраиваемых модулях.
- Используйте точные названия процедур из вставки и порядок параметров.
VALиSTR— названия IGCSE и не дают баллов;UCASEиLCASE— реальные процедуры 9618 из Pseudocode Guide, но они работают с одним символом, поэтому на Paper 2 для всей строки требуетсяTO_UPPERилиTO_LOWER. - В ответе «напишите псевдокод» заголовок, объявления, цикл, условие, обновление и
RETURNполучают балл каждый: напишите все шесть частей, даже если одна вызывает сомнения.
Распространенные ошибки
- Вызов функции без использования возвращаемого значения. Присвойте результат или используйте его в выражении или выводе:
Sorted ← BubbleSort(MyArray, 7). - Передача длины равной единице:
6для массива из семи элементов, или последний индекс, где требовалась длина. Решите, является ли параметр длиной или индексом, и убедитесь, что последний элемент посещен. - Закрытие файла внутри цикла, который его читает. Откройте один раз, закройте один раз, после цикла.
- Использование входных данных напрямую как имени файла. Добавьте расширение, указанное в задании:
FileName ← Choice & ".txt". - Оставленные открытыми конструкции. У каждой
IFдолжна быть свояENDIF, у каждогоFOR— свойNEXT, у каждогоWHILE— свойENDWHILE, и у каждой функции — свойRETURN; схема оценивания предусматривает балл за это. - Неправильные границы: использование
>для выражения «по крайней мере» (что соответствует ⟨⟩>=) или использование индексаFOR, начинающегося с ⟨⟩0, для массива, объявленного размером ⟨⟩[1:50]. - Счетчик или сумма, которые никогда не устанавливаются в
0перед циклом. - В таблице трассировки переписывание каждой переменной на каждой строке или изменение значения до выполнения оператора, который его изменяет.
- Половина условия: использование
IF x = 3 OR 4— каждая сторона оператораORиANDдолжна быть полным сравнением. И оператор+не соединяет строки; это делает оператор&. - Объявление как локального значения, которое должно сохраняться между вызовами. Накопительная сумма или строка, собираемая несколькими вызовами, являются глобальными или
BYREF.
Интерактивные уроки по этой теме
Пройдите его шаг за шагом с упражнениями мгновенной проверки.