HOME»基本情報技術者試験掲示板»単方向リスト append(追加)のサンプル問題について
投稿する

単方向リスト append(追加)のサンプル問題について [5889]

 kalkanさん(No.1) 
サンプル問題の単方向リストの追加ですが、
一つ分からないことがあります。

大域: ListElement: listHead ← 未定義の値

↑これなんですけど、これってlistHeadが最初から
未定義を入れてるんです。
つまり、もうこの単方向リストは、「データありません」
ということで、この先のプログラムのIF文で
listHeadが未定義か?と聞いてくるですが、
このプログラムは、いつもlistHeadは、未定義じゃないのか?
と思うんですが、皆さんいかが考えますか?

===============

手続 append は,引数で与えられた文字を単方向リストに追加する手続である。単方向リ
ストの各要素は,クラス ListElement を用いて表現する。クラス ListElement の説明を図に
示す。ListElement 型の変数はクラス ListElement のインスタンスの参照を格納するものと
する。大域変数 listHead は,単方向リストの先頭の要素の参照を格納する。リストが空の
ときは,listHead は未定義である。

〔プログラム〕
大域: ListElement: listHead ← 未定義の値
○append(文字型: qVal)
2025.05.05 17:12
QMさん(No.2) 
FE ゴールドマイスター
ええと、この問題ですかね。
https://www.fe-siken.com/kakomon/sample20220425/b3.html

確かに最初は未定義です。
なので、初めてappendが呼び出されたときは、
>この先のプログラムのIF文で
>listHeadが未定義か?と聞いてくるですが、
ここで listHead ← curr が実行されます。
この時点で、listHead は未定義ではなくなります。

大域変数なので、appendの処理が終わった後もこの状態は保持されます。
次にappendが呼び出されたときは、未定義ではありません。
append関数の中で未定義を代入するわけではありませんから。
2025.05.05 17:51
まーぼさん(No.3) 
FE シルバーマイスター
参照型の変数は、インスタンスのアドレスが格納されていると考えれば、普通の整数や文字列を格納している変数と同じように考えられて分かりやすいかと思います。

参照型の変数に未定義の値を代入すると、どこも参照していない状態になります。

例えば、
整数型:nは初期値0が代入される。
というのがあって、
n = 10のように、nに10が代入されれば、nは0から10に変わることは当然のことですよね。

それと同じように、
参照型:xは初期値は未定義の値が代入される。
というのがあって、
x = (適当なアドレス値)、でxにアドレスが代入されれば、xが未定義の状態から、参照する状態に変わることも当然のことです。

そう考えると、
大域: ListElement: listHead ← 未定義の値
というのがあったとしても、この変数はずっと未定義だとはならないと思います。
2025.05.05 18:26
電タックさん(No.4) 
FE ブロンズマイスター
>このプログラムは、いつもlistHeadは、未定義じゃないのか?
問題のプログラムが毎回リスタートした場合はその認識であっています。

試験問題のプログラムはリスタートせず、実行しっぱなしで問題のappend()関数(メソッド)が連続的に呼ばれていると考えたほうが良いです。

分かりやすい例としては
https://www.fe-siken.com/kakomon/sample/b8.html
この問題のprioSched()関数みたいなのがあり、その関数(メソッド)の中でappend()が連続的に呼ばれているような感じです。

問8のように具体的な実行結果を説くタイプではないので省いているのだと思います。
2025.05.05 18:46
 kalkanさん(No.5) 
ゴールドマイスターの方とシルバーマイスターの両方ありがとうございます。
あまりの早い返信に驚きました。
QMさんとまーぼさんの返信読みました。

それでも分からないのはクラスの理解が出来てないから
なのかよくわかりません

問題文——————————————
大域変数 listHead は,単方向リストの先頭の要素の参照を格納する。リストが空のときは,listHead は未定義である。
——————————————————
(単方向リストが存在するときは)
大域変数 listHead は,単方向リストの先頭の要素の参照を格納する。
(単方向リストが存在しないときは)
リストが空のときは,listHead は未定義である。

でも、プログラムは最初から
大域: ListElement: listHead ← 未定義の値
ーと未定義の値を大域に代入してるんです。
つまり、最初(初めての処理)から
単方向リストが存在したときも
最初の処理では(未定義の値)が代入されてしまって
未定義(単方向リストがない)処理が前提なのかな?と
今思ってますが、なんか腑に落ちないんですよ
どうなんでしょう?
2025.05.05 19:48
QMさん(No.6) 
FE ゴールドマイスター
>つまり、最初(初めての処理)から
>単方向リストが存在したときも
>最初の処理では(未定義の値)が代入されてしまって
>未定義(単方向リストがない)処理が前提なのかな?と
>今思ってますが、

No.4で電タックさんが書いているように、これはもっと大きなプログラムの一部と考えるべきです。
どこか別の場所に、appendを呼び出す処理があるはずです。
問題に示されている部分だけでは、appendは定義されているだけで、実行されませんから。

その大きなプログラムでは、最初はリストが空の状態が前提なのでしょう。

もしかしたら、既存のリストへの追加にも対応できるよう、
既存のリストが与えられた場合は、実行開始後、appendを呼び出す前に、
別の処理によってlistHeadを更新するようなプログラムになっているかもしれませんが、
そこはこの問題からは分かりません。

あくまでこれは、文字を一つリストに追加する処理についての問題であり、
その際に文字がまだ一つもなかったら「追加」の時とは違う処理が必要だよね、
という問題です。
2025.05.05 20:52
jjon-comさん(No.7) 
FE プラチナマイスター
基本情報 サンプル問題 科目B 問3
https://www.fe-siken.com/kakomon/sample20220425/b3.html

> それでも分からないのはクラスの理解が出来てないからなのか

いいえ、クラスの理解とは別です。

皆さんのおっしゃっていることと同じなのですが、具体例を挙げてみます。

上記に登場する
○append(文字型: qVal)
から始まる12行分の記述は、手続き(procedure:プロシジャ)の定義です。

手続き(プロシジャ)は「複数の処理を一連のまとまりとして、外部から呼び出して実行できるようにしたもの」ですから、
append() をただ定義しただけで、定義したその append() を外部から呼び出していない上記の〔プログラム〕は実行されません。

もう少し正しく補足すると、
大域: ListElement: listHead ← 未定義の値
は、手続き(プロシジャ)の定義ではありませんので、これだけは実行されます。
しかし、
○append(文字型: qVal) から始まる12行分の記述は、
文法チェックはされますが、その命令は実行されません。

このサンプル問題から、出題者の次の意思が読み取れます。
呼ばれる側である手続きの定義があるということは、
(たとえそれが省略されていようと)それを呼び出す側が当然存在するということを
基本情報の受験者は理解しているべきだと、出題者は想定しているということです。

具体例で述べます。
① 大域: ListElement: listHead ← 未定義の値
② append("k")
③ append("a")
④ append("l")
⑤ append("k")
⑥ append("a")
⑦ append("n")


○append(文字型: qVal)
(以降11行分は省略)
このサンプル問題では ①と⑧ のみを問題文として提示しています。
そして、文字を1つ引数として渡してappend()を呼び出す ②~⑦ のような存在を省略しています。

よって、
①の実行後(②の実行前)の時点では listHeadの中身は「未定義の値」ですが、
②実行後以降は、append()の実行によってlistHeadの中身は更新されています。
2025.05.05 21:10
まーぼさん(No.8) 
FE シルバーマイスター
この投稿は投稿者により削除されました。(2025.05.05 23:23)
2025.05.05 23:23
まーぼさん(No.9) 
FE シルバーマイスター
私のNo.8の回答は改めて問題やスレッドを見るとズレているような気がしたので削除しました。

もし、削除前に読んでいた場合は無視して大丈夫です。他の方の回答を読んだ方が混乱せずに理解できると思います。
2025.05.05 23:27
 kalkanさん(No.10) 
FE オールマイススターの方々ありがとうございます。
皆様のフォロー感謝いたします。
電タックさん(No.4)の投稿でおおよその
概要が分かりQMさん(No.6)、jjon-comさん(No.7)の投稿を交互に見て
理解を深めました。

自分は、てっきりこのプログラムは、大域の宣言から全てをカプセル化(?)とか
モジュール化されサブルーチンの様に、呼び出して
何度も大域から全ての処理をその都度流す
プログラムと思ってました。

この自分の固定観念が中々腑に落ちなかった原因でした。
電タックさん(No.4)のリンク先に続きjjon-comさん(No.7)の
----------------------------------
具体例で述べます。
① 大域: ListElement: listHead ← 未定義の値
② append("k")
③ append("a")
④ append("l")
⑤ append("k")
⑥ append("a")
⑦ append("n")
----------------

○ append(文字型: qVal)
(以降11行分は省略)
----------------------------------
⑧以降はよく意味が分からなかったけど、⑦までで理解できました。

「ああ、こういう使い方するのか!」と、ほぼ9割は理解できたと思います。
私は凄く理解が深まりここで「ありがとうございました。」で終了させても
いいのですが、まだまだ意表をついた良い投稿が出てくるかもしれないので
あえて終了宣言しないでおきます。

ここまで、みなさんありがとう。
そして、アクセス禁止の私に抜け道を用意(?)してくださった
管理人の方に感謝いたします。
2025.05.06 03:43
返信投稿用フォームスパム防止のためにスレッド作成日から40日経過したスレッドへの投稿はできません。
© 2010- 基本情報技術者試験ドットコム All Rights Reserved.

Pagetop