---
title: "スタックとは？LIFO・計算途中の値・関数呼出しの仕組み【基本情報技術者試験】"
description: "スタックのLIFO、push・pop、計算途中の値や戻り番地の保存に加え、科目Aで出る最終状態から命令列を逆向きにたどる解き方を、キューとの違いとあわせて整理します。"
last_modified_at: "2026-07-21"
canonical_url: "https://stemtazoo.github.io/fe/stack/"
section: "fe"
---

## まず結論

スタックとは、**最後に入れたデータを最初に取り出すLIFO（後入れ先出し）のデータ構造**です。

基本情報技術者試験では、次の対応を押さえます。

- 関数呼出し・戻り番地・ローカル変数 → スタック
- 計算途中の値を保存し、後で取り出して使う → スタック
- 最後に入れたものから取り出す → LIFO
- 最初に入れたものから取り出す → キュー
- 最終状態から元の値を求める → 命令を後ろから逆向きにたどる

## 直感的な説明

スタックは、積み重ねた皿のイメージです。新しい皿は一番上に置き、取り出すときも一番上から取ります。

関数Aから関数Bを呼び、さらに関数Bから関数Cを呼ぶ場合、戻る順番はC、B、Aです。呼び出した順番とは逆に戻るため、スタックが使われます。

計算式でも同じです。ある計算の途中結果をいったん積んでおき、別の計算を終えた後で、最後に積んだ途中結果から取り出して計算を続けられます。

## 定義・仕組み

スタックの代表的な操作は次の二つです。

| 操作 | 意味 |
|---|---|
| push | データを一番上に追加する |
| pop | 一番上のデータを取り出す |

A、B、Cの順にpushした場合、popされる順番はC、B、Aです。

### 計算途中の値を保存する

加減乗除を組み合わせた計算では、先に求めた途中結果を一時保存し、別の計算が終わった後で取り出して使うことがあります。

例えば、次のような流れです。

```text
途中結果Aを計算する
push(A)

別の途中結果Bを計算する
A = pop()
AとBを使って次の計算を行う
```

最後に保存した途中結果を最初に使う場面では、LIFOのスタックが適しています。

ただし、スタックは途中にある値を自由に変更したり、好きな位置へ新しい値を挿入したりする構造ではありません。基本操作は、一番上への追加と一番上からの取出しです。

### 関数呼出しとコールスタック

関数や手続を呼び出すときは、呼出し元へ戻るための情報を一時保存します。

- 戻り番地
- 引数
- ローカル変数
- 処理途中の値

これらを呼出しごとに積み重ねる領域を**コールスタック**と呼びます。関数が終了すると、その関数の情報を取り出して呼出し元へ戻ります。

再帰呼出しが深すぎるとスタック領域を使い切ることがあります。これが**スタックオーバーフロー**です。

## 科目Aでどう出る？

次のキーワードが出たらスタックを選びます。

- 後入れ先出し
- LIFO
- pushとpop
- 計算途中の値を一時保存する
- 保存した途中結果を後で取り出して計算する
- 関数呼出し
- 戻り番地
- ローカル変数
- 最後に呼び出した処理から先に戻る

| 説明 | データ構造 |
|---|---|
| 計算途中の値を保存し、後で取り出して利用する | スタック |
| 関数呼出し時の戻り番地を保存する | スタック |
| 格納した順番に取り出す | キュー |
| 到着順や受付順で処理する | キュー |
| 値の大小関係を使って検索する | 2分探索木 |
| 前後の要素を双方向にたどる | 双方向連結リスト |

選択肢では、**一時保存という言葉だけで判断せず、どの順番で取り出すか**を確認します。

- 最後に保存した値から使う → スタック
- 最初に保存した値から使う → キュー
- 中間の値だけを変更する → 単純なスタックの基本操作ではない
- リストの途中へ挿入する → 単純なスタックの基本操作ではない

### 最終状態から逆向きにたどる問題

科目Aでは、pushとpopを実行した**後のスタックだけが示され、最初にpushした値などを逆算する問題**もあります。

前から追ってもpushする値が分からない場合は、命令列を最後から逆向きにたどります。

| 元の命令 | 通常の操作 | 逆向きに戻す操作 |
|---|---|---|
| push | 一番上に値を追加する | 一番上の値を取り除く |
| pop | 一番上の値を取り出す | 取り出された値を積み直す |

例えば、実行後のスタックが次の状態だとします。

```text
上
C
B
A
下
```

最後の命令がpushなら、そのpushで追加された値は現在一番上のCです。逆向きに戻すときは、Cを取り除きます。

```text
上
B
A
下
```

最後の命令がpopなら、元の処理では何らかの値が取り出されています。逆向きでは、その値を一番上に積み直します。

```text
上
？
C
B
A
下
```

取り出された値が分からない場合は、無理に決めずに`？`として置きます。後の命令を逆向きにたどることで、その`？`が取り除かれたり、必要な位置関係だけが分かったりします。

試験中は、次のように判断します。

```text
最初から値が分かる
→ push・popを前から実行する

途中の値が不明で、最終状態が分かる
→ 命令を後ろから逆向きにたどる
```

逆向きに追うときも、操作できる場所は常にスタックの一番上です。

## 科目Bでどう使う？

科目Bでは、pushとpopのたびにスタックの状態を書き換えて追います。

```text
push(A)
push(B)
pop()    → B
push(C)
pop()    → C
pop()    → A
```

計算処理でも、途中結果がどの順番で積まれ、どの値がpopされるかを一つずつ追います。

```text
push(8)      スタック：[8]
push(3)      スタック：[8, 3]
pop()        取り出す値：3、スタック：[8]
push(5)      スタック：[8, 5]
pop()        取り出す値：5、スタック：[8]
```

頭の中だけで追わず、処理ごとに「スタックの中身」と「取り出した値」を小さな表やメモに書くと安全です。

## よくある誤解・混同

### 一時保存ならキューでもよい

重要なのは保存できるかではなく、取り出す順番です。最後に保存した途中結果から先に使う場合や、最後に呼び出した関数から先に戻る場合はスタックを使います。

### 格納した順番に取り出すのがスタック

これはキューです。スタックは格納した順番とは逆に、最後に格納した値から取り出します。

### スタックの途中にある値を直接変更できる

単純なスタックで直接操作できるのは一番上の値です。途中の値だけを変更したり、途中へ新しい値を挿入したりする処理には向きません。

### 戻り番地だけを保存する

戻り番地だけでなく、引数、ローカル変数、処理途中の値なども保存します。

### pushとpopを逆に覚える

pushは追加、popは取出しです。popした値はスタックから取り除かれます。

### 逆向きでもpushは値を積む

これは誤りです。命令列を逆向きに戻すときは、元のpushによって追加された一番上の値を取り除きます。

```text
通常のpush
→ 一番上に追加する

pushを逆向きに戻す
→ 一番上を取り除く
```

同様に、元のpopを逆向きに戻すときは、取り出された値を一番上へ積み直します。

## 確認問題（基本情報技術者試験対策）

複数の計算を行う処理で、先に求めた途中結果を一時保存し、別の計算を行った後、最後に保存した途中結果から取り出して計算を続ける。この処理に適したデータ構造はどれか。

- ア. キュー
- イ. スタック
- ウ. 2分探索木
- エ. 双方向連結リスト

<details markdown="1">
<summary>▶ クリックして答えと解説を見る（ここを開く）</summary>

**正解：イ**

- キューはFIFOで、最初に保存した値から取り出します。
- スタックはLIFOで、最後に保存した途中結果から取り出す処理に適しています。
- 2分探索木は値の大小関係を利用した検索に使います。
- 双方向連結リストは前後の要素をたどったり、要素を挿入・削除したりする構造です。

</details>

## まとめ（試験直前用）

- スタックはLIFO（後入れ先出し）
- pushは追加、popは取出し
- 科目Aでは最終状態から命令を逆向きにたどる問題もある
- 逆向きでは、pushは一番上を取り除き、popは値を積み直す
- popされた値が不明なら`？`として位置関係を追う
- 関数呼出し時の戻り番地やローカル変数を保存する
- キューはFIFO（先入れ先出し）
- 再帰が深すぎるとスタックオーバーフローが起こる
