Процедуры, функции и структурированное программирование
| English | Русский |
|---|---|
| subroutines/ˈsʌbruːtiːnz/ | подпрограммы |
| function/ˈfʌŋkʃn/ | функцией |
| procedure/prəˈsiːdʒə/ | процедура |
| structured programming/ˈstrʌktʃəd ˈprəʊɡræmɪŋ/ | структурное программирование |
| decomposition/ˌdiːkɒmpəˈzɪʃn/ | разложение |
| parameters/pəˈræmɪtəz/ | параметрами |
| arguments/ˈɑːɡjuːmənts/ | аргументы |
| signature/ˈsɪɡnɪtʃə/ | подпись |
| 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/ | область применения |
A tape of routines anyone could borrow
- By 1951 the EDSAC team in Cambridge kept a library of subroutines on punched paper tape: square roots, printing, logarithms. Any program could read one in and call it.
- The hard part was getting back. David Wheeler's trick, the "Wheeler jump", stored the return address so a routine could return to wherever it had been called from.
- Every function call you write today does the same thing, and every language library descends from that tape.
- This lesson is procedures and functions: how to define them, how to pass values in and out, and how to write one the way Paper 2 marks it.
Procedures and functions
- Structured programming 结构化编程 builds a program from small named subroutines 子程序, each with one job.
- A procedure 过程 is a named block that does an action and returns nothing:
PROCEDURE Greet(Name : STRING) … ENDPROCEDURE, run withCALL Greet("Ada"). - A function 函数 returns a value that becomes part of an expression:
FUNCTION Square(X : INTEGER) RETURNS INTEGER … RETURN X * X … ENDFUNCTION, used asResult ← Square(5) + 1.

A procedure does something; a function hands back a value
Стек вызовов: push при вызове, pop при возврате
Вызов подпрограммы помещает новый кадр на вершину стека; возврат из неё удаляет этот кадр и возвращает значение вызывающему коду. Вызываемая функция всегда соответствует кадру на вершине стека.
Ключевое отличие процедуры от функции заключается в том, что функция:
Функция возвращает значение (используется в выражении); процедура выполняет действие и ничего не возвращает.
Функция Square(x) возвращает x * x. Что возвращает вызов Square(5)?
5 × 5 = 25 — значение, которое функция возвращает вызывающему коду (кадр удаляется со стека вызовов).
Where each is appropriate
- A procedure where the same group of steps is needed at several points: validate an input, print a menu, swap two values. The steps are written once and called by name.
- A function where a single value must be calculated and then used in an expression: a total, a
TRUE/FALSEresult, the larger of two numbers. The return value replaces the call. - Use a subroutine when logic appears in more than one place, when a block has a clear named purpose, when the program is complex enough to need decomposition 分解, or when you want to test one piece on its own.
Хорошая причина для написания подпрограммы заключается в том, что:
Подпрограммы устраняют дублирование, придают Named purpose (именованную цель) и могут тестироваться изолированно.
Parameters, arguments and the interface
- Parameters 参数 are the variables a subroutine declares to receive values; the values the caller supplies are the arguments 实参.
- The header is the first line:
PROCEDURE Name(Param : TYPE)orFUNCTION Name(Param : TYPE) RETURNS TYPE. The interface, or signature 签名, is the name, the parameters in order with their types, and the return type: everything a caller must know. - The return value is what a function passes back with
RETURN.
Сопоставьте каждый термин с его значением.
Функция vs процедура = возвращает значение или нет; по значению vs по ссылке = копия или оригинал.
Worked example: describe each term in a header
FUNCTION Pass2(Count : INTEGER) RETURNS BOOLEAN.FUNCTION: a subroutine that returns a value.Pass2: the identifier used to call it.Count: the parameter, the identifier that receives the argument passed in.INTEGER: the data type of that parameter.RETURNS BOOLEAN: the data type of the value the function returns. Five parts, one mark each.
В FUNCTION Pass2(Count : INTEGER) RETURNS BOOLEAN идентификатор Count является ____.
Параметр получает аргумент, переданный вызывающим кодом, и используется внутри функции как локальная переменная.
Pass by value and pass by reference
- Pass by value 传值: the routine receives a copy, so changes inside it do not reach the caller. Use it for inputs the routine only reads.
- Pass by reference 传引用: the routine receives a reference to the caller's own variable, so changes do reach the caller. Use it when the routine must update the argument, as in
Swap. - Cambridge writes the mode in the header,
BYVALorBYREF, before each parameter. If neither is written,BYVALis assumed.

A copy, or a link to the caller's variable
Worked example: what is output?
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
Xis a reference toA, soAbecomes 8.Yis a copy ofB, so doublingYleavesBat 3.- The output is
8, 3. Had the header saidBYVAL X,Awould still be 5.
В разобранном примере, каково значение A после вызова CALL Adjust(A, B)?
X передается BYREF, поэтому X ← X + Y добавляет 3 к переменной A вызывающего кода: 5 + 3 = 8. B остается равным 3, так как Y была копией.
Local and global variables
- A local variable 局部变量 is declared inside a subroutine and exists only while it runs; a global variable 全局变量 is declared outside and is visible everywhere. The region where a name is visible is its scope 作用域.
- Locals are preferred: the same identifier can be reused elsewhere without a clash, the value cannot be changed accidentally by other parts of the program, the memory is released on return, and the subroutine is self-contained.
- A local is created new on every call, so it cannot carry a value between calls. A routine that builds up a string over repeated calls needs that string to be global, or passed
BYREF.

A global is visible everywhere; a local lives only inside its own subroutine
Локальная переменная существует только внутри подпрограммы, где она объявлена, в то время как глобальная переменная видна во всем коде программы.
Сохранение переменных локальными ограничивает их область действия, избегает коллизий имен и делает подпрограмму тестируемой самостоятельно — глобальные переменные следует избегать.
Каковы преимущества использования локальных переменных? Выберите все подходящие варианты.
Локальная переменная создается заново при каждом вызове, поэтому она не может сохранять значение между вызовами. Это единственная задача, которую вместо этого выполняет глобальная переменная или параметр BYREF.
Turning a procedure into a function
- Change
PROCEDUREtoFUNCTIONand addRETURNS <type>to the header. - Replace the
OUTPUT, or theBYREFparameter that carried the result out, with aRETURNstatement. - Change every call so the returned value is used:
Result ← Unpack(Text)instead ofCALL Unpack(Text, Result).
Чтобы преобразовать процедуру в функцию, измените заголовок на FUNCTION с RETURNS, замените OUTPUT на RETURN и измените вызовы для использования возвращаемого значения.
Три изменения, три балла: заголовок, RETURN и вызовы.
Worked example: writing a module for Paper 2
- A global array
Score : ARRAY[1:50] OF INTEGERholds test scores. Write a functionCountAbove(Limit : INTEGER)that returns how many scores are greater thanLimit.
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
- The scheme awards a mark per feature: the header with parameter and return type, the local declarations, the counter initialised before the loop, the loop over every element, the condition with the right comparison, the update inside it, the constructs closed, and one
RETURNafter the loop. - An unfinished module still scores for every correct part, so write all of them.

Each part of a module answer carries its own mark
Расположите части ответа модуля Paper 2 в порядке их написания.
Заголовок, объявление, цикл, условие, обновление, возврат. Каждая часть — это отдельный балл, даже если другая часть неверна.
Marks that slip away
- A routine that must change the caller's variable needs
BYREFin its header; without itBYVALis assumed and the change is lost. - A function has one
RETURN, after the loop, andENDFUNCTION. ARETURNinside the loop ends it on the first element. DECLAREevery local, and initialise a counter or total to 0 before the loop.- "Efficient pseudocode" means moving work that does not change out of the loop, stopping a search at the first match, and not repeating a call whose result could be stored.
Чтобы сделать цикл более эффективным, значение, которое не изменяется счетчиком цикла, должно быть:
Вынесение инварианта цикла наружу предотвращает повторное вычисление одного и того же значения на каждой итерации.
You've got it
- a procedure does an action and is
CALLed; a function returns a value used in an expression - the header names the routine, its parameters with types and the return type; arguments are the values passed in
- BYVAL passes a copy (the default); BYREF lets the routine change the caller's variable
- prefer local variables; a local is new on every call, a global keeps its value
- a Paper 2 module: header, declarations, initialisation, loop, condition, update, closed constructs, one
RETURN