基本情報技術者試験過去問 令和7年度(2025年)科目B問3
次のプログラム中のaとbに入れる正しい答えの組合せを,解答群の中から選べ。ここで,配列の要素番号は1から始まる。
関数pushは,引数で与えられた整数をスタックに格納する。格納できた場合はtrueを返し,格納できなかった場合はfalseを返す。
関数popは,スタックから値を取り出して返す。スタックが空のときは未定義の値を返す。
スタックを,要素数が4である大域の整数型の配列stack,及び次に値を格納する位置を示す大域の変数stackPosで表現する。スタックの初期状態を図に示す。
プログラムでは,配列の領域外を参照してはならないものとする。

-----------
〔プログラム〕
大域: 整数型: stackPos ← 3
大域: 整数型の配列: stack ← {4, 3, 未定義の値, 未定義の値}
○論理型: push(整数型: inputData)
if (stackPos ≦ stackの要素数)
stack[a] ← inputData
stackPos ← stackPos + 1
return true
else
return false
endif
○整数型: pop( )
整数型: popData ← 未定義の値
if (stackPos > 1)
stackPos ←b
popData ← stack[stackPos]
stack[stackPos] ← 未定義の値
endif
return popData
-----------

選択肢
- ア
- イ
- ウ
- エ
正解と解き方・学習ポイント(AI解説)
stackPosは「次に値を格納する位置」を表します。pushでは、stackPosが指す要素番号に格納してからstackPosを1増やします。popでは、取り出す要素は直前に格納した位置なので、配列を参照する前にstackPosを1減らし、その位置の値を取り出します。これにより、スタックの動作(後入れ先出し)と配列の領域外参照防止を両立します。
Point
この問題は、配列で実装したスタックにおいて、stackPosを「次に格納する位置」と定義したときに、pushとpopでどの順番でstackPosを更新し、どの添字で配列にアクセスするかを理解しているかを確認するものです。あわせて、要素番号が1から始まる配列で領域外参照を起こさない条件になっているかを確認します。
解くために必要な知識
この問題を解くには、スタックの性質(LIFO)と、配列でスタックを表現する際の管理変数(stackPos)の意味を理解している必要があります。
用語の整理
| 用語 | 意味 |
|---|---|
| スタック | 最後に格納したデータを最初に取り出す(LIFO)データ構造です。 |
| push | スタックにデータを追加する操作です。 |
| pop | スタックからデータを取り出す操作です。 |
| LIFO | Last-In First-Out。後に入れたものを先に取り出します。 |
| stackPos | この問題では「次に値を格納する位置」を示す変数です。 |
配列で表すときの基本ルール
1. stackPosが指す位置の定義
この問題のstackPosは次のルールです。
-
stackPosは、次にpushで書き込む要素番号を指します。
-
すでに格納済みの最後の要素番号は stackPos - 1 になります。
2. pushの処理(追加)
-
書き込み先: stack[stackPos]
-
書き込み後: stackPosを1増やす
まとめると次の形になります。
-
stack[stackPos] ← inputData
-
stackPos ← stackPos + 1
3. popの処理(取り出し)
-
取り出し対象の位置: stackPos - 1
-
手順: stackPosを1減らしてから、その位置の要素を読む
まとめると次の形になります。
-
stackPos ← stackPos - 1
-
popData ← stack[stackPos]
-
stack[stackPos] ← 未定義の値
境界条件(領域外参照を避ける条件)
push側
-
stackPos ≦ stackの要素数 のときだけ書き込み可能です。
-
配列の要素番号は1からなので、最大でstack[4]までです。
pop側
-
stackPos > 1 のときだけ取り出し可能です。
-
これにより、stackPos ← stackPos - 1 をしてもstackPosが0になりません。
問題の解法手順
解く手順
1. stackPosの意味を確認します
問題文より、stackPosは次に値を格納する位置です。
初期状態は stackPos = 3、stack[1] = 4、stack[2] = 3 なので、次に格納するのは要素番号3です。
2. pushのaを決めます
pushでは「次に格納する位置」に格納し、その後で次の空き位置に進めます。
-
格納: stack[stackPos] ← inputData
-
更新: stackPos ← stackPos + 1
よって a = stackPos です。
3. popのbを決めます
popでは最後に格納した値を取り出しますが、stackPosは「次に格納する位置」なので、最後に格納した位置は stackPos - 1 です。
pop内の処理順は次のとおりです。
-
位置を戻す: stackPos ← stackPos - 1
-
取り出す: popData ← stack[stackPos]
-
消す: stack[stackPos] ← 未定義の値
よって b = stackPos - 1 です。
4. 配列領域外参照にならないことも確認します
-
pushの条件は stackPos ≦ stackの要素数(要素数4)なので、stackPosが4以下のときだけstack[stackPos]に書き込みます。
-
popの条件は stackPos > 1 なので、stackPos - 1 が1以上になり、stack[0]の参照を避けられます。
選択肢ごとの解説
- ア:不正解
aがstackPosなのは適切です。一方、bがstackPos + 1だと、popでstackPosを増やしてから配列を参照するため、最後に格納した要素を取り出せず、未使用領域や領域外を参照する可能性があります。よって誤りです。
- イ:正解
aがstackPosなので、pushは「次に格納する位置」に格納できます。bがstackPos − 1なので、popは参照前に直前の格納位置へ戻してからstack[stackPos]を参照します。スタックの後入れ先出しの動作になり、領域外参照も避けられます。よって正解です。
- ウ:不正解
aがstackPos − 1だと、pushで「次に格納する位置」ではなく1つ手前に格納しやすく、既存の要素を上書きする可能性があります。さらにbがstackPos + 1だと、popで取り出し位置が逆になり、正しく取り出せません。よって誤りです。
- エ:不正解
bがstackPos − 1はpopとして適切です。しかしaがstackPos − 1だとpushの格納位置が定義(次に格納する位置)と一致せず、上書きが起こる可能性があります。よって誤りです。
まとめ
stackPosは「次に値を格納する位置」を表します。pushでは、stackPosが指す要素番号に格納してからstackPosを1増やします。popでは、取り出す要素は直前に格納した位置なので、配列を参照する前にstackPosを1減らし、その位置の値を取り出します。これにより、スタックの動作(後入れ先出し)と配列の領域外参照防止を両立します。
aがstackPosなのは適切です。一方、bがstackPos + 1だと、popでstackPosを増やしてから配列を参照するため、最後に格納した要素を取り出せず、未使用領域や領域外を参照する可能性があります。よって誤りです。
aがstackPosなので、pushは「次に格納する位置」に格納できます。bがstackPos − 1なので、popは参照前に直前の格納位置へ戻してからstack[stackPos]を参照します。スタックの後入れ先出しの動作になり、領域外参照も避けられます。よって正解です。
aがstackPos − 1だと、pushで「次に格納する位置」ではなく1つ手前に格納しやすく、既存の要素を上書きする可能性があります。さらにbがstackPos + 1だと、popで取り出し位置が逆になり、正しく取り出せません。よって誤りです。
bがstackPos − 1はpopとして適切です。しかしaがstackPos − 1だとpushの格納位置が定義(次に格納する位置)と一致せず、上書きが起こる可能性があります。よって誤りです。