CS Tutor
Reference · OCR J277, H046 & H446

OCR Exam Reference Language

Every construct, with a worked example, taken from OCR's own specifications rather than from a revision site. Then the two things nobody tells you: exactly how much of it you have to memorise, which is not what most students assume, and the four places the notation quietly costs marks.

Junaid Khalid, software engineer and Computer Science tutor · Reviewed September 2026

01

What it is, and what it used to be called

Exam Reference Language is the notation OCR uses to print program code in exam papers. It exists so a code question reads the same whether a school teaches Python, C# or VB.NET. The GCSE J277 specification puts it flatly: all programming code given in examination papers will be presented using the OCR Exam Reference Language.

Three naming facts cause most of the confusion online, and they are worth getting straight before you revise from anything.

It used to be called the OCR Pseudocode Guide. The J277 specification's own summary of updates lists “OCR Pseudocode guide is now the OCR Exam Reference Language”, and explains the format was changed to be easier to read with more examples included. So a page about the OCR Pseudocode Guide is about this, just under the old name.

OCR's A-Level specifications still say Pseudocode. This one is genuinely untidy on OCR's part. Search the H446 and H046 specifications for the phrase “Exam Reference Language” and you will not find it: both call the appendix Pseudocode. The new name landed at GCSE and has not reached the A-Level documents. Same notation family, two live names.

And OCR is now Cambridge OCR. The H446 specification states that as of September 2025 the board's name is Cambridge OCR, and that students who sat exams in summer 2025 receive Cambridge OCR branded certificates. Older resources keep the OCR or Oxford Cambridge and RSA name. This is not Cambridge International: see the last question below, because the two boards are now easy to confuse and their pseudocode notations are not compatible.

One practical consequence of all this. The GCSE specification names Exam Reference Language but only prints the operator table. The fullest published definition of the syntax sits in the A-Level H446 specification appendix. I checked it line by line against the 2015 GCSE Pseudocode Guide and the constructs are identical, which is why the A-Level appendix is a safe reference for a GCSE student. Everything below comes from those documents.

02

What you actually have to memorise

This is the most common question and it has two different answers depending on which exam you are sitting. Nearly every summary online gives one of them and presents it as the rule.

At A-Level, you do not have to memorise it. The H446 and H046 specifications say it in as many words: learners are not expected to memorise the syntax of this pseudocode, and when asked may provide answers in any style of pseudocode they choose, providing its meaning could be reasonably inferred by a competent programmer. That is unusually generous wording, and it means an A-Level answer is judged on whether a competent reader can follow your logic.

At GCSE, the rule for write and refine questions is much stricter. In J277 Component 2 Section B, an answer to a write or refine question must be in Exam Reference Language or in a high-level programming language the student is familiar with. The specification then says what happens otherwise: answers written in pseudocode, natural English or bullet points will not be awarded marks.

Read that twice, because the trap runs opposite to instinct. At GCSE the risky answer is the vague one. “Loop through the array and add each item to a total” is a correct algorithm and scores nothing. Precise code scores. So the safe habit for a GCSE student is to write real, exact code, almost always Python, rather than hand-wavy pseudocode.

What both levels require is reading fluency. Every code extract in the paper is printed in this notation, so if you have to decode myFile.endOfFile() or 17 DIV 5 under time pressure, you are spending marks worth of minutes on translation before you reach the actual question. That, not memorisation, is the reason to know it cold.

03

Variables, scope and casting

Assignment is a single =. A variable is declared the first time it is assigned, and it takes the data type of the value it is given, so there is no separate declaration line and no type keyword. This is the biggest single difference from Cambridge International notation, which requires an explicit DECLARE.

Assignment and type inferenceerl
x = 3
name = "Bob"
No declaration, no type. x is an integer because 3 is, and name is a string because “Bob” is.

Scope is implicit and follows the subroutine boundary. Variables declared inside a function or procedure are local to it. A variable in the main program is made global with the global keyword.

Global scopeerl
global userid = 123

Casting uses three functions, named exactly as Python names them, which is convenient and also a trap worth noting in section 13.

Castingerl
str(3)        // returns "3"
int("3")      // returns 3
float("3.14") // returns 3.14
04

Input and output

Output is print. Input is input, which takes the prompt shown to the user and returns what they typed.

Output and inputerl
print("hello")

name = input("Please enter your name")
Note the shape of input: the prompt is the argument, and the typed value is the return. It is the Python pattern, not a separate prompt-then-read pair.
05

Selection

Two forms: if with elseif, and switch with case. Both have their own closing keyword, and mixing them up is a free mark lost in a code-completion question.

if / elseif / elseerl
if entry == "a" then
    print("You selected A")
elseif entry == "b" then
    print("You selected B")
else
    print("Unrecognised selection")
endif
then on the if and on each elseif, never on the else. Closed with endif. One word: elseif, not else if and not elif.
switch / caseerl
switch entry:
    case "A":
        print("You selected A")
    case "B":
        print("You selected B")
    default:
        print("Unrecognised selection")
endswitch
Colons after the switch expression and after each case. The catch-all is default, and the block closes with endswitch. There is no fall-through to worry about and no break.
06

Iteration

Three loops, and this is where the notation is least like anything else. Each has a different terminator, and one of them is not an end word at all.

Count controllederl
for i = 0 to 7
    print("Hello")
next i
Closed with next i, naming the loop variable, not with endfor. The bounds are inclusive: this prints eight times, 0 to 7.
Pre-conditionerl
while answer != "computer"
    answer = input("What is the password?")
endwhile
Condition checked before each pass. Closed with endwhile.
Post-conditionerl
do
    answer = input("What is the password?")
until answer == "computer"
Runs at least once, then checks. Closed by until and its condition, with no enddo. Note the condition is inverted relative to the while version above: this one loops until the condition becomes true.
07

Operators

The comparison and boolean operators are the only part of the notation the GCSE specification itself prints, in section 3c. Note that assignment is = and equality is ==, exactly as in Python.

Comparison

==
Equal to
!=
Not equal to
<
Less than
<=
Less than or equal to
>
Greater than
>=
Greater than or equal to

Boolean, written in capitals

AND
Logical AND
OR
Logical OR
NOT
Logical NOT

Arithmetic

+
Addition
-
Subtraction
*
Multiplication
/
Division. 12 / 2 gives 6
MOD
Modulus, the remainder. 12 MOD 5 gives 2
DIV
Quotient, integer division. 17 DIV 5 gives 3
^
Exponentiation. 3 ^ 4 gives 81

MOD, DIV and ^ are the three that catch people. In Python they are %, // and **, so a student who has only ever typed Python meets three unfamiliar symbols in a paper that also expects them to be quick.

08

Strings

Strings use dot methods. Length is a property with no brackets; substring takes a start position and a number of characters, not an end position, which is the difference that breaks most answers.

Length and substringerl
someText = "Computer Science"

print(someText.length)
print(someText.substring(3, 3))
Prints 16, then put. Strings are 0-based, so position 3 is the fourth character, and the second argument is a count: three characters from index 3 gives p, u, t.

The .length property takes no brackets, unlike Python's len() function. If you write someText.length() you have written something that is neither notation.

09

Arrays

Arrays are declared with the array keyword and are 0-based. The number in the declaration is the number of elements, so valid indices run from 0 to one less than that.

One-dimensionalerl
array names[5]
names[0] = "Ahmad"
names[1] = "Ben"
names[2] = "Catherine"
names[3] = "Dana"
names[4] = "Elijah"

print(names[3])
Prints Dana. Five elements, indices 0 to 4. There is no names[5].

Two-dimensional arrays use one pair of brackets with a comma, not two pairs.

Two-dimensionalerl
array board[8,8]
board[0,0] = "rook"
board[0,0], not board[0][0]. Python programmers reach for the second form by reflex.
10

Subroutines

Two kinds, distinguished by whether they return a value. function returns, procedure does not. Each has its own closing keyword.

Function: returns a valueerl
function triple(number)
    return number * 3
endfunction

y = triple(7)
Procedure: does not returnerl
procedure greeting(name)
    print("hello" + name)
endprocedure

greeting("Hamish")
Called as a bare statement, not assigned to anything. Getting function and procedure the wrong way round is a reliable way to lose a mark on a “which subroutine would you use” question.

Parameters are passed by value unless stated otherwise. Where it matters to the question, OCR marks it explicitly with byVal and byRef.

Explicit passing modeerl
procedure foobar(x:byVal, y:byRef)
    ...
endprocedure
Colon syntax, inside the parameter list. If you see neither keyword, assume by value.
11

File handling

Files open in one of two modes and are handled through methods on the returned object. Reading uses openRead and readLine; writing uses openWrite and writeLine. Both close with close.

Read one lineerl
myFile = openRead("sample.txt")
x = myFile.readLine()
myFile.close()
Read the whole fileerl
myFile = openRead("sample.txt")
while NOT myFile.endOfFile()
    print(myFile.readLine())
endwhile
myFile.close()
endOfFile() is a method with brackets, and it is negated with the capitalised NOT. This exact loop is the one worth memorising, because it appears constantly.
Writeerl
myFile = openWrite("sample.txt")
myFile.writeLine("Hello World")
myFile.close()
Worth knowing for a “what does this program do” question: openWrite overwrites any previous contents. There is no append mode in the notation.

Comments are // to end of line, as in C or JavaScript, not # as in Python.

Commentserl
print("Hello World") // This is a comment
12

Objects, at A-Level only

Object-oriented constructs appear in the A-Level specifications only. They are not part of GCSE J277, so a GCSE student can stop here.

Methods and attributes are public unless stated. Where access level matters to the question it is written explicitly with public and private. Methods are always instance methods: OCR states learners are not expected to be aware of static methods.

Attributes and methodserl
private attempts = 3

public procedure setAttempts(number)
    attempts = number
endprocedure

public function getAttempts()
    return attempts
endfunction

player.setAttempts(5)
print(player.getAttempts())

A constructor is a procedure named new. Inheritance uses inherits, and a superclass method is reached with super, so a parent constructor call is super.new().

Class, constructor and inheritanceerl
class Pet
    private name

    public procedure new(givenName)
        name = givenName
    endprocedure
endclass

class Dog inherits Pet
    private breed

    public procedure new(givenName, givenBreed)
        super.new(givenName)
        breed = givenBreed
    endprocedure
endclass
class closes with endclass. The subclass constructor calls super.new() first, then sets its own attributes.

One more A-Level note that surprises people. The H446 specification also expects learners to follow and write basic JavaScript, covering the JavaScript equivalents of the structures above, but explicitly not for object-oriented programming or file handling. It also says exam questions will not penalise minor JavaScript syntax inaccuracies, and will not ask about passing by value or reference in JavaScript.

13

Side by side with Python

Exam Reference Language is close enough to Python to feel familiar and different enough to catch you out. Since most OCR students learn Python and are allowed to answer in it, the useful skill is knowing precisely where the two diverge. Here is the same program in both.

Exam Reference Languageerl
global total = 0
array scores[4]
scores[0] = 12
scores[1] = 7
scores[2] = 20
scores[3] = 3

for i = 0 to 3
    if scores[i] MOD 2 == 0 then
        total = total + scores[i]
    endif
next i

print("Even total: " + str(total))
The same thing in Pythonpython
total = 0
scores = [12, 7, 20, 3]

for i in range(4):
    if scores[i] % 2 == 0:
        total = total + scores[i]

print("Even total: " + str(total))
Both print Even total: 32. Five differences in eleven lines: the loop bound is inclusive in one and exclusive in the other, MOD against %, then and endif against a colon and indentation, next i against nothing, and an explicit array size against a list literal.
IdeaExam Reference LanguagePython
Remainder12 MOD 512 % 5
Integer division17 DIV 517 // 5
Power3 ^ 43 ** 4
Boolean andANDand
Count loopfor i = 0 to 7 ... next ifor i in range(8):
Post-condition loopdo ... until x == 1while True: ... break
Else ifelseif ... thenelif ...:
Block endendif, endwhile, endfunctionindentation
String lengths.lengthlen(s)
Substrings.substring(3, 3)s[3:6]
2D indexboard[0,0]board[0][0]
Comment//#

Scroll the table sideways

14

The four places this costs marks

1. Answering a GCSE write question in vague pseudocode. Covered in section 2 and worth repeating because it is the expensive one. In J277 Component 2 Section B, generic pseudocode, natural English and bullet points are not awarded marks. Write real code.

2. Off-by-one on the count-controlled loop. for i = 0 to 7 runs eight times, because the bounds are inclusive. A student converting from Python's range(7), which runs seven times, gets a trace table one row short and loses every mark that depends on the final value.

3. Treating the second substring argument as an end position. substring(3, 3) is three characters starting at index 3. Python's s[3:3] is the empty string and s[3:6] is the equivalent. This single confusion produces more wrong string answers than anything else in the notation.

4. Closing the wrong block. There are five different terminators, endif, endwhile, endswitch, endfunction and endprocedure, plus next i and until, which are not end words at all. Complete-the-code questions test exactly this, and it is a mark you either have or do not.

15

Gaps in OCR's own guide

Reading the specifications closely, a few things are genuinely underspecified. Worth knowing so you do not waste time hunting for an answer that is not published.

Object creation is never shown. The A-Level appendix defines a constructor as a procedure called new and then calls player.setAttempts(5) on an object named player, without ever showing how player came into existence. There is no published line for instantiating an object. In an exam this does not matter much, since your logic is what is being read, but it means any tutorial confidently showing you “the” OCR instantiation syntax is inventing it.

The guide contradicts itself on substring capitalisation. The definition is written stringname.subString(...) with a capital S, and the worked example immediately below writes someText.substring(3,3) with a lowercase s. Both appear in the same section of the same document. Nothing to worry about, since either will be read correctly, but if you were wondering which is right: OCR has not decided.

There is no append mode for files, and no error handling at all. openWrite overwrites. There is no documented equivalent of try or catch, no exception model, and no way to express a failed file open. If a question needs that, it will be asked in natural English.

And the full GCSE syntax is not in the GCSE specification. J277 names Exam Reference Language and prints only the operator table. Everything else on this page had to come from the A-Level appendix and the legacy guide. That is a documentation gap on OCR's side, and it is most of the reason a page like this needed writing.

16

Questions

What is OCR Exam Reference Language?

It is the pseudocode-style notation OCR uses to print program code in Computer Science exam papers, so that code questions read the same way regardless of which programming language a school teaches. The GCSE J277 specification states that all programming code given in examination papers is presented in OCR Exam Reference Language.

Is Exam Reference Language the same as the OCR Pseudocode Guide?

Yes, it is the same notation under a newer name. The J277 specification's own summary of updates says the OCR Pseudocode guide is now the OCR Exam Reference Language, and that the format was changed to be easier to read with more examples. Confusingly, OCR's A Level specifications still call it Pseudocode, so both names are current depending on which document you are reading.

Do I need to memorise Exam Reference Language syntax?

At A Level, no. The H446 and H046 specifications say learners are not expected to memorise the syntax and may answer in any style of pseudocode whose meaning could reasonably be inferred by a competent programmer. At GCSE the answer is different and stricter: in J277 Component 2 Section B, write and refine answers must be in Exam Reference Language or a high-level programming language, and answers in generic pseudocode, natural English or bullet points are not awarded marks. Either way you need to read it fluently, because every code extract in the paper is printed in it.

Are arrays 0-based or 1-based in Exam Reference Language?

0-based. OCR states arrays will be 0 based and declared with the keyword array. Strings are 0-based too, which is the detail that most often breaks a substring answer.

Can I just write Python in an OCR exam?

In most cases yes, and often you should. OCR accepts answers in Exam Reference Language or in a high-level programming language the student is familiar with. Python is the usual choice. What you cannot do at GCSE is write something vague that is neither: loose pseudocode and English prose score nothing on write and refine questions.

Is OCR the same as Cambridge International?

No, though the names now invite the mistake. OCR renamed itself Cambridge OCR as of September 2025. It is the UK board behind GCSE J277 and A Level H446. Cambridge International, or CAIE, is a separate board behind IGCSE 0478 and 0984 and AS and A Level 9618, with its own and quite different pseudocode notation. Both sit under Cambridge University Press & Assessment. Go by the specification code, not the word Cambridge.

Sources

Checked against the specifications, not revision sites

Specifications get revised. If a detail here disagrees with the current specification, the specification is right and I would genuinely like to know: the point of this page is to be the version that is correct.

Reading it is one thing. Writing it under time pressure is another.

A reference tells you what the syntax is. It cannot tell you why your trace table came out one row short, or why an answer that looked right scored two out of four. That is what a lesson is for: your paper, your code, on screen, line by line.

I teach OCR J277 at GCSE and OCR H446 at A-Level, alongside AQA, Edexcel and Cambridge IGCSE, which matters here for one specific reason: I can tell you which pseudocode habit belongs to which board, and which one to drop. £60 an hour, free introductory call first.

More free guides in the resources hub, including A-Level NEA project ideas.