コンテンツへスキップ

高度なプログラミング

A-Levelコンピュータ科学 · トピック 20

查看幻灯片 練習する
このトピックのビデオレッスン 動画ページを開く
13:52

プログラミングのパラダイム

ここで一つのタスクがあります:A gradeを取得した生徒をすべてリストアップすることです。あるプログラマーはループを書きます——最初のレコードから始め、gradeを確認し、名前をリストに加え、移動します…

英語ナレーション・英語+中文字幕 burning-in

20.1

プログラミングパラダイム

シラバス
受験者は以下的能力を備えているべきである: メモおよびガイドライン
プログラミングパラダイムの概念を理解する。
多数のプログラミングパラダイムの特徴の理解を示す。
• 低レベル 低レベルプログラミング: • 多様なアドレッシングモード(即座に、直接、間接、インデックス、相対)を使用した低レベルコードの理解および記述能力。
• 命令型(手続型) 命令型(手続型)プログラミング:• 構造化プログラミングに関する既知の知識と理解(AS内容セクション11.3の詳細を参照)• 変数、構造体、プロシージャ、関数を用いた命令型(手続型)プログラミングコードの記述に関する理解と能力。詳細はAS内容を参照
• オブジェクト指向 オブジェクト指向プログラミング(OOP):• OOPに関連する用語の理解(オブジェクト、プロパティ/属性、メソッド、クラス、継承、多様性、包含(集約)、カプセル化、ゲッター、セッター、インスタンスを含む)• 適切なクラスを設計して問題を解決する方法の理解• OOPの使用を示すコードを記述する理解と能力
• 宣言型 宣言型プログラミング:• 提供された情報に基づいて適切な事実とルールを記述し、問題解決を行うための理解と能力• 事実とルールを用いてゴールを満たすことができるコードを記述する理解と能力

出典: Cambridge International シラバス

プログラミングパラダイムとは、プログラムのスタイル、すなわちプログラムを構成する方法そのものであり、独自の考えや言語機能を持つ。このシラバスには4つのプログラミングパラダイムが含まれる。

"命令型(手続型)言語が何を意味するか説明せよ(2点)。プログラムが指令の列であり、順次実行され、プログラムの状態を変化させる言語である;プログラマーはプロシージャ、シーケンス、選択、反復を使用して、どうやってタスクを遂行するかを指定する。 "宣言型言語が何を意味するか説明せよ:*プログラムは事実とルール(何を知っているか、何が求めているか)を記述し、言語の推論エンジンが答えを見つける方法を計算する;プログラマーは手順の列を指定しない。"

コードサンプルからパラダイムを特定する(通常Paper 3の問題):LDD 200, ADD #5, STO 201は低レベル(mnemonics、レジスタ、メモリアドレス);FOR Count ← 1 TO 10 … NEXT Countはプロシージャと代入を含む命令型;CLASS Dog … PRIVATE Name : STRING … PUBLIC PROCEDURE NEW(…)はオブジェクト指向;type(lion, wild).とdangerous(X) IF type(X, wild)は宣言型(ロジック)。マッチング問題では:低レベルは「機械命令に直接対応するmnemonics」、命令型は「状態を変化させる文の列」、OOPは「属性とメソッドを組み合わせたオブジェクト」、宣言型は「実行順序が指定されていない事実とルール」に対応する。

Four paradigms: low-level, imperative, object-oriented and declarative
四つのパラダイム:低レベル、命令型、オブジェクト指向、宣言型

低レベルプログラミング

ハードウェアに近い マシンコードまたはアセンブリ言語でのプログラミングで、各指令がCPUが実行する内容に対応する。レジスタとメモリアドレスへの直接アクセスを提供し、異なるアドレッシングモード(即時、直接、間接、インデックス、相対)を使用する。非常に高速かつコンパクトだが、アーキテクチャ固有であり、退屈で保守が難しい。これは低レベルプログラミングであり、デバイスドライバ、ファームウェア、ブートローダーに使用される。

5つのアドレッシングモード。シラバスでは、各アドレッシングモードを用いた低レベルコードを問う(指令セットはトピック4)。ロード指令の演算数は5通りの読み方が可能であり、試験ではメモリ contents が与えられ、アクセミュレータが何を持っているかを問う:

A memory table with addresses 105, 106, 107, 27 and 145 and their contents, beside five rows showing what the accumulator receives from LDM #105, LDD 105, LDI 105, LDX 105 with IX = 2, and a relative jump
同じ演算数105を5通りで読む:値として、アドレスとして、アドレスのアドレスとして、アドレス+インデックスレジスタとして、現在の指令からのオフセットとして
  • 即時 (LDM #105):演算数がそのまま値であり、ACCは105になる。
  • 直接 (LDD 105):演算数が値のアドレスであり、ACCは105の内容(ここでは27)になる。
  • 間接 (LDI 105):演算数がアドレスのアドレスであり、ACCは27の内容(ここでは91)になる。ポインタや、実行時に位置が決定されるデータに使用される。
  • インデックス (LDX 105):アドレスは演算数**+インデックスレジスタIX**であり、IX=2の場合、ACCは107の内容になる。IXを増加させて配列をステップアップするために使用される。
  • 相対 (JMR +65):ターゲットは現在の指令のアドレスからのオフセットであり、これがコードの可搬性を可能にする。

** worked example(演習例)。** メモリ: 105に27、106に64、200に0が格納されている。105と106の内容を加算し、結果を200に格納して出力するコードを記述せよ。LDD 105 (ACC = 27)、ADD 106 (ACC = 91)、STO 200、OUT。105の値を倍にする場合: LDD 105、ADD 105、STO 105。トレースを求められた場合、各行実行後のレジスタの内容を記述せよ。

命令型(手続型)プログラミング

命令型プログラミングでは、プログラマーはプログラムの状態を変化させる一連のコマンド(代入、条件分岐、ループ、関数呼び出し)を書く。変数が状態を保持し、ステートメントがそれを変化させ、コードはプロシージャと関数(構造化プログラミングとも呼ばれる)に組織される。これはトピック9と11のスタイル(Python, C)である。アルゴリズムに明確な順次步骤がある場合に強い。

オブジェクト指向プログラミング(OOP)

オブジェクト指向プログラミングでは、プログラムはオブジェクトから構築される——データ(属性)と操作(メソッド)を組み合わせる単位である。オブジェクトはクラスのインスタンスである。4つの柱:

  • カプセル化 — オブジェクトのデータはメソッドの背後に隠されており、外部コードは公開メソッドのみを使用し、データを直接参照しない。これによりオブジェクトが保護され、内部の実装が変わっても呼び出し側が破損しない。例えば、BankAccountは自身のbalanceを隠しており、deposit()とwithdraw()を通じてのみ変更可能であり、"ゼロ以下にならない"のようなルールを強制できる。
  • 継承 — サブクラスがスーパークラスを特殊化し、自身の属性とメソッドを継承し、追加または上書きする。「is-a」("マネージャーは従業員である")をモデル化する。
  • ポリモーフィズム — 異なるオブジェクトが同じメソッド呼び出しに異なる反応を示す;呼び出し側は正確なタイプを知る必要はない。すべてのShapeがArea()を持ち、CircleとRectangleそれぞれが独自の方法で実装する。
  • 抽象化 — simpleなインターフェースを示し、実装を隠す。

他の用語:

  • コンストラクタは、オブジェクトが作成されたときに実行される特別なメソッドであり、自身の属性を設定するために使用される。
  • ゲッターとセッターは、メソッドを通じてオブジェクトの属性(自身のプロパティ)を読み書きする。
  • 集約(aggregation) と 包含(containment) は、他のオブジェクトから一つのオブジェクトを構成する(「has-a」関係)。

OOPは、大規模システム、GUI、シミュレーション、ゲームに用いられる。

同じ呼び出し形状。Area()が各オブジェクトで異なるコードを実行する:Circleはπ×半径の二乗を計算し、Rectangleは幅×高さを計算する
多様性:同じメソッド呼び出しが、各オブジェクト固有のコードを実行する
ShapeのためのUMLクラス図:クラス名、private属性(Name, Area, Perimeter、マイナス印付き)、publicメソッド(SetShape, calculateArea, calculatePerimeter、プラス印付き)を持つ3部分のボックス
Shapeのためのクラス図:private属性とpublicメソッド
UML継承図:上部にemployee超クラス、その下にpartTimeとfullTimeサブクラス。それぞれが超クラスに空心三角形の一般化矢印で接続され、独自の属性とメソッドを追加している
継承:partTimeとfullTimeはemployeeのサブクラスである
BankAccountオブジェクト:privateのbalanceはpublicメソッドdeposit()とwithdraw()を通じてのみアクセス可能であり、外部コードがデータを直接触れることはできない
カプセル化:オブジェクトのデータはprivateであり、publicメソッドを通じてのみアクセスできる

出題者が採点するOOP

定義。 クラス: そのタイプのオブジェクトの属性とメソッドを定義するテンプレート(設計図)。オブジェクト: クラスのインスタンスであり、そこから作成され、属性に対して独自の値を持つ(「オブジェクトの発生」という表現は、試験におけるインスタンスの言い換えである)。属性(プロパティ): クラスに属するデータ項目。メソッド: クラスに属し、その属性に対して動作する手続や関数。カプセル化: 属性とメソッドを1つのクラスにまとめ、データへの外部アクセスを制限すること:属性はprivateであり、publicメソッドを通じてのみ読み書きできる。継承: サブクラスが親(超)クラスの属性とメソッドを取得し、独自に追加したり上書きしたりできる。多様性: 同じ名前を持つメソッドが、異なるクラスで異なる振る舞いをする;一般的には、サブクラスが親のメソッドを再定義し、各オブジェクトに対して正しいバージョンが実行される。包含: クラスが別のクラスのオブジェクトを属性として持つ(車はエンジンを持つ)。「データへの外部アクセスを制限する特徴を特定せよ」はカプセル化、「オブジェクトの発生に対する用語」はインスタンスである。

「クラスの構造を説明せよ」(3点): オブジェクトのデータを保持する属性(プロパティ)、通常privateで宣言されます;_att_的属性act upon those attributes, usually public; and a constructor, a method that runs when an object is created to initialise the attributes. "Give three benefits of OOP": code is reused through inheritance; data is protected by encapsulation, so it can only be changed by the class's own methods; a large program is split into classes that are written and tested independently, so it is easier to maintain and extend; classes model real-world entities, so the design is easier to understand; polymorphism lets the same call work for different objects.

疑似コードでのクラス、Paper 3の設定通り:

CLASS Car
    PRIVATE Registration : STRING
    PRIVATE Year : INTEGER
    PRIVATE Mileage : INTEGER
    PUBLIC PROCEDURE NEW(NewReg : STRING, NewYear : INTEGER)
        Registration ← NewReg
        Year ← NewYear
        Mileage ← 0
    ENDPROCEDURE
    PUBLIC FUNCTION GetMileage() RETURNS INTEGER
        RETURN Mileage
    ENDFUNCTION
    PUBLIC PROCEDURE AddMileage(Extra : INTEGER)
        Mileage ← Mileage + Extra
    ENDPROCEDURE
ENDCLASS

オブジェクトはMyCar ← NEW Car("AB12 CDE", 2020)によって作成され、MyCar.AddMileage(150)およびOUTPUT MyCar.GetMileage()によって使用される。サブクラスは親のコンストラクタをSUPERを通じて再利用する:

CLASS ElectricCar INHERITS Car
    PRIVATE BatteryCapacity : REAL
    PUBLIC PROCEDURE NEW(NewReg : STRING, NewYear : INTEGER, NewCapacity : REAL)
        SUPER.NEW(NewReg, NewYear)
        BatteryCapacity ← NewCapacity
    ENDPROCEDURE
ENDCLASS

Pythonでの同一クラス、Paper 4の要件通り:属性はダブルアンダースコアでprivateにし、コンストラクタは__init__であり、サブクラスは親を括弧内に指定してsuper().__init__(…)を呼び出す:

class Car:
    def __init__(self, reg, year):
        self.__registration = reg
        self.__year = year
        self.__mileage = 0
    def get_mileage(self):
        return self.__mileage
    def add_mileage(self, extra):
        self.__mileage = self.__mileage + extra

class ElectricCar(Car):
    def __init__(self, reg, year, capacity):
        super().__init__(reg, year)
        self.__capacity = capacity

cars = []
cars.append(Car("AB12 CDE", 2020))
cars.append(ElectricCar("EV21 XYZ", 2023, 75.0))
cars[1].add_mileage(150)
print(cars[1].get_mileage())

Javaでは、同様の概念がprivate/publicフィールド、クラスの名称を持つコンストラクタ、extendsおよびsuper(…)です。VB.NETではPrivate/Public、Sub New、Inherits、MyBase.Newです。多様なメソッドは親に記述され、同じ名前で子においてオーバーライドされ、親型の変数を通じた呼び出しでは子のバージョンが実行される。

オブジェクトとしてのデータ構造。 Paper 4は、データと他ノードへの1つまたは2つの参照を持つ属性のNodeクラスからスタック、リンクedList、二分木を構築します。Tree(またはLinkedList)クラスはルート(または先頭)とメソッドを保持する。

Nodeオブジェクトの二項木:TreeオブジェクトのRootはノード15を指し、そのLeftとRightRef参照はノード8と19を指し、空の参照にはNoneを使用する
オブジェクトから構築された二項木:各NodeはData、Left、RightRef参照を持ち、TreeはRootを持ちます; 挿入は参照をたどって下行します
CLASS Node
    PUBLIC Data : INTEGER
    PUBLIC Left : Node          // NULL when there is no child
    PUBLIC RightRef : Node
    PUBLIC PROCEDURE NEW(NewData : INTEGER)
        Data ← NewData
        Left ← NULL
        RightRef ← NULL
    ENDPROCEDURE
ENDCLASS

CLASS Tree
    PRIVATE Root : Node
    PUBLIC PROCEDURE Insert(NewData : INTEGER)
        DECLARE NewNode, Current : Node
        DECLARE Placed : BOOLEAN
        NewNode ← NEW Node(NewData)
        IF Root = NULL THEN
            Root ← NewNode
        ELSE
            Current ← Root
            Placed ← FALSE
            WHILE NOT Placed
                IF NewData < Current.Data THEN
                    IF Current.Left = NULL THEN
                        Current.Left ← NewNode
                        Placed ← TRUE
                    ELSE
                        Current ← Current.Left
                    ENDIF
                ELSE
                    IF Current.RightRef = NULL THEN
                        Current.RightRef ← NewNode
                        Placed ← TRUE
                    ELSE
                        Current ← Current.RightRef
                    ENDIF
                ENDIF
            ENDWHILE
        ENDIF
    ENDPROCEDURE
ENDCLASS

findメソッドは同じ経路をたどり、Current.Data = TargetでTRUEを返す;NULLに到達するとFALSEを返す;中順出力メソッドは再帰的である:左部分木、ノード、右部分木の順に出力する。リンクedListの場合、ノードは1つの参照Nextを持ち、リストクラスはStartを保持する;リストから構築されたスタックでは、pushとpopはどちらもStartで動作する。

** worked example.** A game has characters. Each has a name, health (starting at 100) and a position given by X and Y. Write a class Character with a constructor and a method Move(DX, DY); then a subclass Wizard that adds Mana (starting at 50) and a method CastSpell() that takes 10 mana and returns TRUE if there was enough.

CLASS Character
    PRIVATE Name : STRING
    PRIVATE Health : INTEGER
    PRIVATE X : INTEGER
    PRIVATE Y : INTEGER
    PUBLIC PROCEDURE NEW(NewName : STRING, StartX : INTEGER, StartY : INTEGER)
        Name ← NewName
        Health ← 100
        X ← StartX
        Y ← StartY
    ENDPROCEDURE
    PUBLIC PROCEDURE Move(DX : INTEGER, DY : INTEGER)
        X ← X + DX
        Y ← Y + DY
    ENDPROCEDURE
ENDCLASS

CLASS Wizard INHERITS Character
    PRIVATE Mana : INTEGER
    PUBLIC PROCEDURE NEW(NewName : STRING, StartX : INTEGER, StartY : INTEGER)
        SUPER.NEW(NewName, StartX, StartY)
        Mana ← 50
    ENDPROCEDURE
    PUBLIC FUNCTION CastSpell() RETURNS BOOLEAN
        IF Mana >= 10 THEN
            Mana ← Mana - 10
            RETURN TRUE
        ELSE
            RETURN FALSE
        ENDIF
    ENDFUNCTION
ENDCLASS

得点は、private属性、すべての属性を設定するコンストラクタ、継承の線、親のコンストラクタへの呼び出し、オブジェクト自身のデータを使用・変更するメソッドである。問題がクラス図を求める場合は、3部分(名前;privateを示す-付きの属性;publicを示す+付きのメソッド)のボックスを描き、サブクラスを親に向けて矢印で接続する。

宣言的プログラミング

宣言型プログラミングでは、どうやって計算するかではなく、何を計算するかを指定します。実行環境が手順を決定します。2つの種類があります:

  • 関数型プログラミング — 純粋関数(副作用なし;同じ入力には常に同じ出力)を組み合わせて構築されます。例:Haskell, Lisp。
  • 論理型プログラミング — 事実とルールを定義し、エンジンが推論によってゴール(クエリ)に回答します。例:Prolog。

よく知られた宣言型の例としてSQLがあります:SELECT * FROM Customer WHERE Country = 'UK' はレコードを参照する手順ではなく、何が欲しいかを述べています。

事実、ルール、ゴールは宣言型パラダイムにおける試験の出題ポイントです。事実(真である命題)とルール(条件が満たされれば成り立つ結論)が与えられたとき:

01 type(leopard, wild).
02 type(lion, wild).
03 type(tabby, domestic).
04 size(leopard, large).
05 size(lion, large).
06 size(tabby, small).
07 dangerous(X) IF type(X, wild) AND size(X, large).

"Goal type(X, wild)の結果を記せ": X = leopard, X = lion。エンジンは goal を各 fact と順に照合し、一致するごとに解となります。大文字は 変数 であり、照合によって値が入力されます。"シマウチが野生であることを示す fact を記せ": type(cheetah, wild). "Line 07が何をするか説明せ": 結論dangerous(X)を持つルールを定義しており、野生かつ大型のXであれば真となるため、dangerous(A)はA = leopard, A = lionを返します。"ルールを記せ:身体スタイルBに対して機能Fが利用可能であるのは、Fが機能であり、Bが身体スタイルであり、かつFがBにおいて利用不可でない場合のみである: may_be_available(F, B) IF feature(F) AND body_style(B) AND NOT unavailable(F, B)。問題のfactで使用された predicated名と引数の順序をそのままコピーすること。新しいfactは句読点(。)で終わり、ルールの条件はANDで接続される。

パラダイムの比較

パラダイム 強み 代表的な言語
ローレベル 最大の制御性、高速性 アセンブリ
命令型 直接的、直感的 C, Python
オブジェクト指向 モジュール化、実体のモデル化 Java, C#, Python
関数型 明確、副作用なし Haskell, F#
論理型 推論、ルール Prolog
データベース データクエリ SQL

現代の言語は多くの場合パラダイムを混合します—Pythonは手続的、OOP、関数的のすべてをサポートしています。適切な選択は問題次第です。

探索

プログラミング概念ラボ

各例とそれが示すプログラミングの概念を結びつけてください。

探索

One binding must satisfy both conditions

Trace a fixed two-condition rule through supplied facts. A failed candidate can lead to another binding; a missing fact leaves a goal unproved.

English 日本語
programming paradigm/ˈprəʊɡræmɪŋ ˈpærədaɪm/ プログラミングパラダイム
facts/fækts/ 事実
rule/ruːl/ ルール
low-level/ləʊ ˈlevl/ 低レベル
registers/ˈredʒɪstəz/ レジスタ
memory addresses/ˈmeməri əˈdresɪz/ メモリアドレス
objects/ˈɒbdʒekts/ オブジェクト
attributes/ˈætrɪbjuːts/ 属性
methods/ˈmeθədz/ メソッド
machine code/məˈʃiːn kəʊd/ 機械語
assembly language/əˈsemblɪ ˈlæŋɡwɪdʒ/ アセンブリ言語
addressing modes/əˈdresɪŋ məʊdz/ アドレス指定モード
array/əˈreɪ/ 配列
imperative programming/ɪmˈperətɪv ˈprəʊɡræmɪŋ/ 命令型プログラミング
Variables/ˈveərɪəblz/ 変数
object-oriented programming/ˈɒbdʒekt ˈɔːrɪəntɪd ˈprəʊɡræmɪŋ/ オブジェクト指向プログラミング
instances/ˈɪnstənsɪz/ インスタンス
classes/ˈklæsɪz/ クラス
encapsulation/ɪnˌkæpsjʊˈleɪʃn/ カプセル化
inheritance/ɪnˈherɪtəns/ 継承
subclass/ˈsʌbklæs/ サブクラス
superclass/ˈsuːpəklæs/ スーパークラス
overriding/ˌəʊvəˈraɪdɪŋ/ オーバーライド
polymorphism/ˈpɒlɪmɔːfɪzəm/ 多様性
abstraction/əbˈstrækʃn/ 抽象化
constructor/kənˈstrʌktə/ コンストラクタ
aggregation/ˌæɡrɪˈɡeɪʃn/ 集約
containment/kənˈteɪnmənt/ 包含
declarative programming/dɪˈklærətɪv ˈprəʊɡræmɪŋ/ 宣言的プログラミング
functional programming/ˈfʌŋkʃənl ˈprəʊɡræmɪŋ/ 関数型プログラミング
pure functions/pjʊə ˈfʌŋkʃnz/ 純粋関数
side effects/saɪd ɪˈfekts/ 副作用
logic programming/ˈlɒdʒɪk ˈprəʊɡræmɪŋ/ 論理_programming
SQL/ˌes kjuː ˈel/ 構造化クエリ言語
20.2

ファイル処理

シラバス
受験者は以下的能力を備えているべきである: メモおよびガイドライン
ファイル処理操作を行うコードを記述する (読み取り、書き込み、追記モードで)ファイルを開き、閉じる ファイルからレコードを読み取り、ファイルにレコードを書き込む シリアル、シーケンシャル、ランダムファイルに対するファイル処理操作を実行する
例外および例外処理の重要性に関する理解を示す 例外処理を使用する適切なタイミングを知る 例外処理を使用するプログラムコードを記述する

出典: Cambridge International シラバス

これはトピック10のファイル操作を拡張し、シリアル、シーケンシャル、およびランダム(直接アクセス)ファイルを処理します。擬似コード演算子:OPENFILE name FOR READ | WRITE | APPEND (READは既存ファイルを開く、WRITEは作成または上書き、APPENDは末尾に追加);READFILE name, line;WRITEFILE name, value;CLOSEFILE name;そしてEOF(name)は終端でTRUEとなる。

ファイル全体を読む:

OPENFILE "names.txt" FOR READ
WHILE NOT EOF("names.txt") DO
    READFILE "names.txt", thisName
    OUTPUT thisName
ENDWHILE
CLOSEFILE "names.txt"

ファイルを検索(見つかったら停止):

found ← FALSE
OPENFILE "people.txt" FOR READ
WHILE NOT EOF("people.txt") AND NOT found DO
    READFILE "people.txt", line
    IF line = target THEN
        found ← TRUE
    ENDIF
ENDWHILE
CLOSEFILE "people.txt"

ファイルのインプレース更新

ほとんどの言語はテキストファイルをインプレースで編集できません。代わりに:元のファイルはREAD用、一時的なファイルはWRITE用で開き、各行について変更が必要な場合は新しいバージョンを書き込み、そうでない場合は元のままを書き込み、両方を閉じ、最後に元のファイルを一時ファイルで置き換えます。このパターンは行の削除(スキップ)や挿入にも適用されます。

インプレースでのファイル更新:元のファイルを読み込み、変更行を一時的なファイルに書き込み、その後元のファイルを一時的なファイルで置き換える
インプレースでのファイル更新:元を読み込み、変更を一時的なファイルに書き込み、その後元のファイルで置き換える

レコードと直接アクセスファイル

開き方(Opening modes)。 READ: ファイルが存在する必要があり、読み込みは先頭から始まる。WRITE: 新しい ファイルを作成し、同名の既存ファイルは 上書き される。APPEND: 書き込みは既存ファイルの 末尾 に追加される。開いたすべてのファイルはCLOSEFILEで閉じられ、最終項目を読み込んだ後、EOF(name)はTRUEとなる。

3つのファイル構成。 シリアルファイルではレコードは追加された順序で並び、シーケンシャルファイルではキー順で並び、どちらも先頭から読み出せる。ランダムファイル(直接アクセスファイル)はハッシュ関数によりキーから計算されたアドレスに各レコードを格納するため、他のレコードを読むことなく1つのレコードを見つけることができる。レコードはユーザー定義型として宣言される:

TYPE AccountRecord
    DECLARE AccNo : INTEGER
    DECLARE Name : STRING
    DECLARE Balance : REAL
    DECLARE Active : BOOLEAN
ENDTYPE
キー2317をMOD 1000でハッシュしてアドレス317とし、ファイルAcc.datに対してSEEKおよびGETRECORDを行い、等サイズのレコードスロットの列として表示し、スロット317を強調表示
ランダムファイル内の1つのレコードの検索:キーがアドレスにハッシュされ、ファイルポインタがそのスロットに直接シークされ、レコードが読み出される;他のレコードは触れない

擬似コードにおけるランダムファイル演算子はOPENFILE "Acc.dat" FOR RANDOM、SEEK "Acc.dat", Address(ファイルポインタをそのレコードへ移動)、GETRECORD "Acc.dat", Rec(そこにレコードを読む)およびPUTRECORD "Acc.dat", Rec(そこにレコードを書く)である。Paper 3で設定されているようにアカウント番号で顧客を探すために:

DECLARE Rec : AccountRecord
DECLARE Target, Address : INTEGER
INPUT Target
Address ← Target MOD 1000              // the hashing function
OPENFILE "Acc.dat" FOR RANDOM
SEEK "Acc.dat", Address
GETRECORD "Acc.dat", Rec
WHILE Rec.AccNo <> Target AND Rec.AccNo <> 0    // 0 marks an empty slot
    Address ← Address + 1               // a collision: try the next slot
    SEEK "Acc.dat", Address
    GETRECORD "Acc.dat", Rec
ENDWHILE
IF Rec.AccNo = Target THEN
    OUTPUT Rec.Name, Rec.Balance
ELSE
    OUTPUT "No such account"
ENDIF
CLOSEFILE "Acc.dat"

レコードを格納するには、キーをハッシュし、SEEKでアドレスへシークし、PUTRECORDを行う。すでに占有されているスロットを踏んで進む。ハッシュへのMarks、GETまたはPUT前のSEEK、ターゲットとの比較、衝突の処理、ファイルの閉じ方に Marksがつく。

** worked example.** ActiveFile.dat は AccountRecord 個のレコードを持つ。Activeフィールドが FALSE である全レコードを ArchiveFile.dat の末尾へコピーする擬似コードを記せ。

DECLARE Rec : AccountRecord
OPENFILE "ActiveFile.dat" FOR READ
OPENFILE "ArchiveFile.dat" FOR APPEND
WHILE NOT EOF("ActiveFile.dat")
    READFILE "ActiveFile.dat", Rec
    IF Rec.Active = FALSE THEN
        WRITEFILE "ArchiveFile.dat", Rec
    ENDIF
ENDWHILE
CLOSEFILE "ActiveFile.dat"
CLOSEFILE "ArchiveFile.dat"

Pythonのテキストファイル(Paper 4):file = open("HighScore.txt", "r")、次にfor line in file:でline.strip()とline.split(",")を用いて fields を分離し、int(…)でスコアを変換し、file.close()を行う;書く場合はopen(name, "w")(または"a"で追加)とfile.write(str(score) + "\n")。高得点表はレコードのリストに読み込まれ、新しいスコアがその位置に挿入され、全体のリストが書き戻される。 examinors は正しいモードでのopen、各行を読むloop、テキストから数値への変換、closeにMarksをつける。

注意点

ファイルのcloseを忘れる(データ損失の可能性);APPEND intended でWRITE open(全て上書き);EOF を超えて読む;ハードコードされたパス—/Users/Admin/data.txtのようなパスは別のマシーンで破損するため、DataFile = "./data/scores.txt"のような相対定数を使用する。

探索

ファイルアクセスルート

ストレージからプログラムへ、そして戻ってくるまでファイルを安全に追跡する。

English 日本語
file/faɪl/ ファイル
random file/ˈrændəm faɪl/ ランダムファイル
hashing/ˈhæʃɪŋ/ ハッシュ
20.2

エクスセプション処理

例外(exception) は、実行中のエラーや予期せぬ状態——ゼロ除算、ファイル未見つかり、ネットワーク障害、配列インデックスの範囲外など——を指す。例外処理(Exception handling) を用いることで、プログラムはこれを 検知 して、クラッシュさせることなく適切に応答できる。

重要である理由は、実際のプログラムが 事前に防止できない エラー(ファイル移動、ネットワークダウン、入力の不備など)に直面するからであり、これがない場合、すべての操作に固有のIFチェックが必要となり、また 通常の流れとエラー処理を分離 することで、メインパスをすっきりしたコードに保てるからである。例えば、ファイル存在確認後に実際には別のユーザーによってファイルが削除される可能性があり、これを阻止することはできず、発生時に失敗を処理するしかない。

「例外とは何かを例示して説明せよ」(2点)。 プログラムの 実行中(ランタイム) に発生する 予期せぬ出来事やエラー であり、通常の流れを中断 する。例として、ゼロでの除算、存在しないファイルの開封、非数値入力の整数への変換、配列インデックスの範囲外、またはメモリの枯渇がある。「例外が発生する2つの原因を列挙せよ」 は上記リストに加え、「デバイスやネットワークが利用できない」「無効なデータ型が入力された」という回答も含まれる。

"例外処理を適用する理由"(3点)。プログラムが** crash (予期せぬ終了)することを防ぐ;システムエラーではなくユーザーに意味のあるメッセージを出力する;例えば入力を再取得したり、終了前にファイルを安全に閉じたりして、プログラムを回復させ継続させる;そして、プログラムを記述した時点では某些のエラーが予測できないためです。「例外によるプログラムの終了を避ける方法」を説明しなさい:** 例外を引き起こす可能性がある文をTRYブロックに配置します。その例外に対応するEXCEPT(キャッチ)ブロックを記述し、メッセージを出力するなどの対応を行うことで、ブロック終了後に実行を継続し、停止しないようにします。「例外処理の定義」を説明しなさい: 例外が発生した際に検知し、それを処理するためのコード(ハンドラ)を実行することで、プログラムを継続させること。)

パターン

TRY
    OPENFILE "data.txt" FOR READ
    READFILE "data.txt", line
    OUTPUT line
    CLOSEFILE "data.txt"
EXCEPT FileNotFound
    OUTPUT "Sorry, the file does not exist."
EXCEPT ReadError
    OUTPUT "Sorry, error reading the file."
ENDTRY

TRYブロックは失敗する可能性があるコードを保持し、最初の一致するEXCEPTブロックが実行される。実際の言語では、Catch-allのEXCEPTと、例外の有無に関わらず実行されるFINALLYブロックも存在する——ファイル閉鎖などのクリーンアップに有用である。

例外フロー: TRYブロックが例外を raised した場合、制御は対応する EXCEPT へジャンプする。例外がない場合はスキップされる。いずれの場合でも FINALLY ブロックは実行され、その後プログラムは継続する
例外フロー: 例外は対応するEXCEPTへジャンプし、FINALLYはプログラムが継続する前に必ず実行される

例外の発生

エラーを検知するサブルーチンは例外を発生させ、呼び出し側で処理させることができます:

FUNCTION Divide(a : INTEGER, b : INTEGER) RETURNS INTEGER
    IF b = 0 THEN
        RAISE DivideByZero
    ENDIF
    RETURN a DIV b
ENDFUNCTION

例外を処理する場所

対応が単純な場合(メッセージ表示や再試行のみ)はエラーに近接して処理し、外側のコードのみが対応策を知っている場合は呼び出しスタックの上層で処理します(例: 上位レベルのGUIループがエラーをログに書き込み、親しいダイアログを表示)。例外を静かに吞み込むことは避けてください — 少なくともログを残さなければ、デバッグができなくなります。

一般的な例外:FileNotFound、IOError、DivisionByZero、IndexOutOfRange、InvalidArgument、NullReference、OutOfMemory。失敗する操作を適切な TRY で囲み、正しい EXCEPT ハンドラを指定することで、クラッシュせずグラシウスに耐えうるプログラムとなる。

worked example (Paper 4). パラメータとしてファイル名を受け取り、各行に1つずつ正整数を読み取ってリストで返す関数を作成します。ファイルが存在しない場合や、各行が正整数でない場合でも crash してはいけません。

def read_scores(filename):
    scores = []
    try:
        file = open(filename, "r")
        for line in file:
            scores.append(int(line))
        file.close()
    except FileNotFoundError:
        print("The file", filename, "does not exist")
    except ValueError:
        print("A line in the file was not a whole number")
    return scores

tryブロックには、失敗する可能性があるコード(openと変換)が含まれます。各exceptは1つの例外を指定し、有効な対応を行います。関数はリストを返すため、呼び出し側も继续できます。Javaでは同じ形はtry { … } catch (FileNotFoundException e) { … } catch (NumberFormatException e) { … }、VB.NETではTry … Catch ex As FileNotFoundException … End Tryです。採点基準: try内のリスクのある文、正しい例外名、各々へのメッセージ、その後のプログラムの継続; catch-allのexcept:はクラッシュ防止にはなるが、「適切な例外」の得点はありません。

** worked example.** メンバーの電話番号変更が必要なテキストファイルがあります。なぜ単にその行を上書きできないのか、そしてどのようなパターンがあるか? テキストファイルの各行は長さ differingしており、差を吸収するスペースがありません。長い代替文なら次のレコードに被り、短いなら古い行の一部が残ります。したがって、パターンは元のファイルをREADモード、一時的なファイルをWRITEモードで開き、各行を順に読み取って、変更される行には新しいバージョンを書き込み、それ以外の行には元の行を書き込み、両方を閉じた後、元のファイルを一時ファイルで置き換えすることです。削除(行をスキップ)や挿入(余分な行を書く)にもこの形が使えます。すべての行が書き込まれることに注意してください。新しいレコードだけを書いて残りを失うのが古典的なミスです。

探索

例外処理の流れ

コードが失敗した際に行われることを順を追って確認する。例外は通常のフローからジャンプしてハンドラへ移り、FINALLYはどちらの場合でも清掃を行い、プログラムは crash せず継続する。

English 日本語
exception/ekˈsepʃn/ 例外
exception handling/ekˈsepʃn ˈhændlɪŋ/ 例外処理
raise/reɪz/ 発生
call stack/kɔːl stæk/ 呼び出しスタック
20.2

出題者が認める定義

定義問題は固定された用語に基づいて採点されます。これらを正確に暗記し、一つの答えのみを答えてください。

用語 定義
プログラミングパラダイム プログラムの構造化方法自体を含む、プログラミングのスタイルや手法
命令型言語 プログラムは状態を変化させる文のシーケンスであり、プログラマがタスクの実装方法を指定する
宣言型言語 プログラムは事実とルールを記述し、推論エンジンが答えを見つける方法を導き出す
クラス そのタイプのオブジェクトのプロパティとメソッドを定義するテンプレート
オブジェクト(インスタンス) クラスの出現であり、プロパティに対して独自の値を持つ
プロパティ クラスに属するデータ項目
メソッド クラスに属し、そのプロパティに対して動作する手続または関数
カプセル化 クラス内で属性とメソッドをまとめ、外部からのデータへのアクセスを制限し、公開メソッド経由でのみ変更可能にする
継承 サブクラスが親クラスの属性とメソッドを継承し、追加または上書きできる
ポリモルフィズム 同じ名前を持つメソッドだが、異なるクラスに対して異なる動作をするもの
コンストラクタ オブジェクトが作成された際に実行され、その属性を初期化するメソッド
包含 クラスが他のクラスのオブジェクトを自身の属性の一つとして持つこと
事実 宣言型プログラムにおいて真である文
ルール その条件が真のときに成り立つ結論
シリアルファイル、シーケンシャルファイル、ランダムファイル 記録の追加順に並べたもの;キー順に並べたもの;各記録のアドレスがキーから計算されるもの
エクセプション 実行中に発生する予期せぬエラーやイベントで、通常の処理フローを中断するもの
エクセプションハンドリング エクセプションが発生した検知とそれに対するコードの実行により、プログラムを継続させること
20.2

試験対策

  • パラダイム: 各パラダイムの1行での説明を理解し、コードサンプルからパラダイムを名指せるようにする;低レベルの問題では5つのアドレッシングモードと累加器に入力される値を問われる。
  • OOPの定義は毎回出題される: クラス、オブジェクト、属性、メソッド、カプセル化、継承、ポリモルフィズム、コンストラクタ。 PRIVATE属性、PUBLIC NEWおよびゲッターを含むクラスを擬似コードで記述すること;INHERITSとSUPER.NEWを含むサブクラスを記述すること。
  • 宣言型: 変数を含むゴールは一致するすべての事実を返す;ルールの結論はANDで結合された条件が真であれば成立する;問題の述語名は正確にコピーすること。
  • ファイル: 3つのモードとそれぞれ既存ファイルに対する操作;WHILE NOT EOFループ内でのREADFILE;ハッシュ、SEEK、GETRECORD、PUTRECORDを使用するランダムファイル(衝突による上書きあり)。
  • エクセプション: 例を伴う定義、エクスセプションハンドリングを行う3つの理由、TRYと名付けられたEXCEPTを用いてプログラムを継続させる方法。

一般的なミス

  • 宣言型プログラムを「答えを与える一連の手順」として説明しない;それは真であることと望まれていることを述べており、どうやってやるかではない。
  • オブジェクトとクラス、またはインスタンスと属性を混同しない;「オブジェクトの occurrence」に関する問題はインスタンスを求めている。
  • 属性をPUBLICとして宣言したり、ゲッターを介さずにクラス外から直接アクセスしたりすると、カプセル化のマークが失われる。
  • サブクラスのコンストラクタで親の属性を直接設定し、SUPERNEWを呼ばない。
  • ポリモルフィズムを「多くのオブジェクト」として説明しない;同じメソッド名が異なるクラスに対して異なる振る舞いをするものだ。
  • FOR WRITEでファイルを開いて記録を追加すると既存の内容が破棄される;APPENDを使用すべきである。
  • ランダムファイルの先頭からの読み出し;最初にハッシュされたアドレスまでSEEKする。
  • エクセプションハンドラーを失敗不可能なコードの周囲に置いたり、メッセージなしで全てをキャッチしたり、エクスセプションハンドリングを「IFで入力チェックすること」として説明したりする。

このトピックのインタラクティブ授業

一歩ずつ進め、即時チェック付きの問題で学習します。

過去問

A-Levelコンピュータ科学 の他のトピック

ログインまたはアカウント作成

IGCSE, A-Level & AP