CHAPTER 5

Questions

1. An ADT is a data type whose representation details are hidden from the user of entities of that type, whereas transparent data type have their representation details visible to the user of entities of that type.

2. The specification of types must include the allowable values and all valid operations.

3. Built-in ordinal types have many pre-specified operations (possibly including +, -, *, /) whereas user-defined ordinal types have only INC, DEC, MAX, MIN, VAL, and ORD. Any other operators must be defined as procedures.

4. When WriteString is called, it expects a variable of the same type (array of char). Here however, the item used is of type MonthNames and therefore will not work with WriteString. The type MonthNames is an ADT of its own.

5. The value Saturday is needed to prevent a run time error when the value Friday is incremented.

6. Advantages:
(i) The subrange is a different abstraction than the original type. Use of the subrange may therefore make a program clearer.
(ii) Some systems may store the values of a subrange more efficiently than those of the original type.
(iii) Error trapping. An error is generated if any attempt is made to assign something to a variable that is not in the subrange.

7. (a) is backwards (b) uses two different types‹a character and a number. The specification for (c) requires prior definition of an enumeration with values a and e.

8. An iterated repetition involves a pre-specified pattern in an arithmetic sequence whereas a more general repetition can use any sequence of numbers, even altering the sequencing on the fly.

9. The FOR loop can only count up or down in constant increments, whereas the WHILE construction places no limitations on manipulating the loop counter variable inside the loop or on using it afterwards.

10. (a) the assignment operator is incorrect.
(b) the FOR loop increments by 1 by default. Therefore, the counter will never get to 1.
(c) "count" should be a CHAR variable; perhaps it's name should be changed
(e) watch out for a possible overflow.
(f) 1.5 is not an ORDINAL type.
(g) 1.5 is not an ORDINAL type.
(h) OK, but misleading, as count is evaluated only of the start and so is one.

11. The reason is that the subrange has a maximum of 10 and when the count reaches 10, it increments one more because the condition on the WHILE has not yet been met. At this point, the range will have been exceeded.

12. (a) 5
(b) adding 2 different data types.
(c) Thursday
(d) may compile but cardValue will not be correct. (cardVar will be taking in an integer).
(e) only allowed to INC using variables.

13. Inside the loop, the control loop variable is being threatened. Outside, it is undefined, so there is no point incrementing it (logical error).

14. The outer control loop variable is being threatened.

15. (a) 33 (b) 9 (c) 892
(d) 68 (e) will not do anything because the start value is already beyond the stop value.

16. Note: _ are used as spaces and cr is used as a carriage return.
(a) cccchhhhoooorrrrdddd
(b) _ _ _ _ _ _ _ _ _5 cr
(c) _1_1_1_2_1_3_2_2_2_3_3_3

17. A two dimensional array is called a matrix.

18. (i) matrix = ARRAY [1..m], [1..n] OF CARDINAL
(ii)

	FOR outer := 1 TO m
	  DO
	    FOR inner := 1 TO n
	      DO
	        matrix [outer, inner] := 0;
	      END;
	  END;

Problems

NOTE: Not all problems are shown. Most problems are left up to students as labs.

(*  Modified
    June.11.1999
    Chapter 5 Question 19  *)

MODULE LetterCount;

(* Written by R.J. Sutcliffe *)
(* to illustrate the use of the for loop *)
(* using ISO Modula-2 *)
(* last revision 1991 02 27 *)

FROM STextIO IMPORT
  ReadString, ReadChar, WriteChar, WriteString, WriteLn, SkipLine;
FROM SWholeIO IMPORT
  WriteCard;
FROM SIOResult IMPORT
  ReadResults, ReadResult;

CONST
  space = CHR (32);
  alpha = CHR (65);
  cr = CHR (13);
  period = ".";
  min = 33; (* Set limits of printable ASCII characters *)
  max = 126;
  maxOnLine = 5;

TYPE
  LetArray = ARRAY CHAR OF CARDINAL;

VAR
  letterCount, wordCount, numOnLine, avPerWord : CARDINAL;
  lets : LetArray;    (* Examples:  lets ['A'], lets [","] *)
  ch, last : CHAR;
  lastResult : ReadResults;
  userDone : BOOLEAN;

BEGIN
  FOR ch := CHR (min) TO CHR (max) (* initialize totals to zero *)
    DO
      lets [ch] := 0;
    END;   (* for *)
  userDone := FALSE;

  WriteString ("Please type in text you want analyzed.");
  WriteString (" End with period at start of line.");
  WriteLn;

  wordCount := 0;
  letterCount := 0;
  last := space; (* now leading space won't be seen as words *)

  REPEAT   (* main loop to read text by characters *)
    ReadChar (ch);     (* reads whatever is next *)
    lastResult := ReadResult ();
    IF lastResult = endOfLine  (* translate end of line state *)
      THEN  (* into 'carriage return character read' *)
        ch := cr;
        SkipLine;
      END;
    IF (lastResult = allRight) AND (ch > space) AND (ch # period)
      (* no control characters counted *)
      THEN
        (* see if it's in the alphabetic range *)
        IF (ch > CHR(64)) AND (ch < CHR(91))
           THEN
             INC (lets [VAL(CHAR, ORD(ch) + 32)]);
             INC (letterCount);
           ELSIF (ch > CHR(96)) AND (ch < CHR(123)) THEN
             INC (lets [ch]);
             INC (letterCount);
           END;
      ELSIF ( (ch = space) AND (last # space) ) OR (ch = cr) AND (last # cr) THEN
        (* two consec. is just one word *)
        INC (wordCount);
      ELSIF (ch = period) AND (last = cr) THEN
        (* end of input *)
        userDone := TRUE;
        SkipLine;
      END;
    last := ch; (* reset last for next time *)
  UNTIL (lastResult = endOfInput) OR userDone;

(* now tell user the results, several to a line *)
  numOnLine := 0;
  WriteLn;
  FOR ch := CHR (min) TO CHR (max)
    DO
      WriteChar (ch);     (* put out character *)
      WriteCard (lets [ch], 5);    (* # of times it was there *)
      WriteString ("     "); (* leave some space; make columns *)
      INC (numOnLine );
      IF numOnLine MOD maxOnLine = 0
        THEN
          WriteLn;
        END;
    END;    (* for *)
  WriteLn;
  WriteLn;
  WriteString ("# of words = ");
  WriteCard (wordCount, 0);
  WriteLn;
  WriteString ("# of letters = ");
  WriteCard (letterCount, 0);
  WriteLn;
  IF wordCount # 0
    THEN
      avPerWord := TRUNC ((FLOAT (letterCount) / FLOAT (wordCount)) + 0.5);
      WriteString ("# of letters/word (nearest whole number) = ");
      WriteCard (avPerWord, 0);
      WriteLn;
    END;

  WriteString ("Press a key to end ==>");
  ReadChar (ch);
END LetterCount.
(* Created June 14, 1999
   Chapter 5 Question 22
   Canned Program *)

MODULE PrintASCII;

FROM STextIO IMPORT
  WriteString, WriteLn, WriteChar, SkipLine;
FROM SWholeIO IMPORT
  WriteCard;

CONST
  start = 32;  (* start at CHR(32) *)
  end = 127;   (* end at CHR(127) to see non used character *)
VAR
  count, colcount, howmany : CARDINAL;

BEGIN
  WriteString ("This program writes out the ASCII character values with its");
  WriteLn;
  WriteString ("corresponding ordinal values.");
  WriteLn;
  WriteLn;
  WriteLn;

  (* initialize vars *)
  howmany := 0;
  colcount := 1;
  count := start;

  (* print them out nicely in a table *)
  WHILE count <= end DO
    WriteChar(CHR(count));
    WriteCard(count, 9);
    WriteString ("        ");   (* 8 spaces for formatting *)

    (* make a table of 2 rows *)
    IF colcount = 2 THEN
      colcount := 0;
      DEC (count, 2*48);    (* go twice back because it incs later *)

      IF (count # 31) THEN  (* make sure it doesn't write same *)
        INC (count, 1);
      ELSE
        count := 128; (* make sure it gets out *)
      END;

      WriteLn;
    END;

    (* inc counters *)
    INC (count, 48);
    INC (colcount);
    INC (howmany);
  END;  (* end WHILE *)

  WriteLn;
  WriteLn;
  WriteCard (howmany, 0);
  SkipLine;
END PrintASCII.