kent logo

CO538 Anonymous Questions and Answers Keyword Index

This page provides a keyword index to questions and answers. Clicking on a keyword will take you to a page containing all questions and answers for that keyword, grouped by year.

To submit a question, use the anonymous questions page. You may find the keyword index and/or top-level index useful for locating past questions and answers.

Keyword reference for array-segments


Question 75 (2004):

Hi, can you talk me through what is happening with the outputs here? Thanks very much.

    string; name.length::name; mark
        out.string ([name FOR name.length], max.name.length, out)
        out.int (mark, max.name.length, out)
        out.string ("*c*n", 0, out)

Answer 75:

This code-fragment is not a valid occam process -- to be meaningful it needs a bit more context (in particular the "in ? CASE" above it, since the line starting "string" is part of the tagged protocol input). As for the outputs: in sequence, this outputs the first "name.length" characters of "name", in a field-width of "max.name.length", then outputs the value held in "mark" (again in a field-width of "max.name.length") and finally outputs a carriage-return/newline pair (strictly speaking only the newline bit is required, so you could just write "out ! '*n'" instead (or "out.string ("*n", 0, out)"). See the course library documentation for a detailed description of these procedures. And the related questions about array-segments for information on the "[name FOR name.length]" expression.

Keywords: out.int , out.string , array-segments

Question 65 (2004):

I was looking through the questions on arrays and as you said arrays have to be of a fixed size and are not initialised by default. So how do you initialise them to be empty or the equivalent of java's null ? Also can arrays of a smaller size be assigned to a larger capacity array (assuming they are of the same type) ? For example:

    [num]BYTE temp := "":

does not work (and neither does ":= []")

Answer 65:

There is no concept of null in occam! There are no objects in occam!!

When we declare an occam array:

    [num]BYTE my.array:

This is (roughly) similar to declaring and constructing a Java array:

    byte[] myArray = new byte[num];

occam variables, including array variables, always refer to allocated space. Whether that space has defined values set in them is up to our program. No default values (e.g. zero) are set. To initialise array values, it's the same as in Java -- simply iterate over the elements, setting them in turn. For example:

    SEQ i = 0 FOR SIZE my.array
      my.array[i] := 0

[Aside: the statement above (that "occam variables ... always refer to allocated space") is strictly true for classical occam. The new occam-pi has mobile data types, space for which is dynamically allocated. So, mobile variables from time to time may not refer to allocated space. However, in that case, the occam-pi language rules (enforced by the compiler) do not allow us to attempt to access their values -- so there remains no concept of null (and null pointer error) that you can fall into, :).]

You can't assign a smaller array to a larger array -- or a larger array to a smaller one. The size of an array is part of that array's type in occam, so different sized arrays are not assignment compatible.

occam does however support something that helps here, that Java doesn't: array segments (someimes called slices -- see the last paragraph of section 5 in the "occam2 Checklist"). A segment expression allows a portion of an array to be used, instead of the whole array. For example:

      [my.array FROM 2 FOR 4] := "fred"

will assign those bytes to 4 bytes of `name', starting at index 2. It is the same as the code:

      VAL []BYTE tmp IS "fred"
      SEQ i = 2 FOR 4
	my.array[i] := tmp[i-2]


	my.array[2] := 'f'
	my.array[3] := 'r'
	my.array[4] := 'e'
	my.array[5] := 'd'

but the segment expression is much more succinct. The other elements of my.array are untouched. Should the above my.array have less than (2 + 4) elements, of course there would be a range error.

Couple of other bits of syntax for these segment expressions: either the FROM part or the FOR part are optional -- but not both! The expression "[my.array FOR n]" means the first n elements of my.array (i.e. "[my.array FROM 0 FOR n]"). The expression "[my.array FROM m]" means the last m elements of my.array (i.e. "[my.array FROM m FOR (SIZE my.array) - m]").

If you want more (!) and like puzzles, check out Question 44 (2002).

Other things raised by your question. In occam, "" and [] represent an array of zero elements -- though these only have limited use. The new KRoC (occam-pi) now recognises `[]' as an empty array of any type ("" is specifically an zero-length array of BYTEs). These are useful as arguments to PROCs or FUNCTIONs that require array arguments, but the particular call does not need to pass any data.

Initialisation and declaration can be combined, but requires a slightly different syntax than what you've got above:

    INITIAL []BYTE name IS "fred":   -- declares and assigns a [4]BYTE array

The LHS and RHS types of the `IS' must match. But I doubt this will be useful here.

Keywords: arrays , array-segments


Question 44 (2002):

What do these mean??

  [array FROM s FOR 1][i]
  [[[array FROM s FOR 1] FOR i][j], 42]

Answer 44:

If X is an array, then X[i] refers to its ith. index element.

Well, [X FROM start FOR n] is an array - it represents the slice of the array X from index start for the next n elements inclusive. [This is explained in the last paragraph of Section 5 of "The occam Checklist" in your course notes.] Of course, if that slice takes us outside the index bounds of the array, that generates a run-time error.


  [X FROM start FOR n][i]

is just the ith. index element of the array [X FROM start FOR n], which is the (start + i)th. index element of the array X, so long as i is in the bounds of [X FROM start FOR n] - i.e. so long as 0 <= i < n. Therefore:

  [array FROM s FOR 1][i]

is only legal if i is zero ... in which case it is the same as element array[s].

If start is zero, then [X FROM start FOR n] may be written as just [X FOR n]. So:

  [[array FROM s FOR 1] FOR i]

is only error free if i is zero or one. If the former, then the above represents a zero-length array for which any further indexing or slicing will throw a run-time error. If the latter, the above represents the same one-length array slice as before - i.e. it's the same as:

  [array FROM s FOR 1]

Continuing with the only legal assumption (that i is one), then:

  [[array FROM s FOR 1] FOR i][j]


  [array FROM s FOR 1][j]

As considered before, the above is only legal if j is zero, in which case it equals:


So, the original expression:

  [[[array FROM s FOR 1] FOR i][j], 42]

is only legal if i is one and j is zero - in which case, it equals:

  [array[s], 42]

So long as s is a legal index of the array array, this is a literal expression of either a two-element array (assuming that array is an array if integers) or a two-field RECORD type. See the answer to Question 45 (2002) for (non-examinable) information on RECORD types.

I'd not ask anyone to work through such a tortuous example in an exam!

Keywords: arrays , array-segments

Referrers: Question 65 (2004) , Question 104 (2003)

Valid CSS!

Valid XHTML 1.0!

This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.
Last modified Mon May 20 13:50:25 2013
This document is maintained by Fred Barnes, to whom any comments and corrections should be addressed.