スタックって何?わかりやすく解説

パソコンやプログラミングの話題で「スタック」って単語、聞いたことありませんか?なんだか難しそうで、実際にはどういう意味なのか、なぜそんな言い方をするのか、さっぱりわからないってことが多いですよね。でも実は、スタックはみんなが毎日経験している「重ねる」という行動をコンピュータに説明したものなんです。この記事を読めば、スタックが何なのか、なぜプログラミングで大事なのか、がすっきりわかるようになりますよ。

先生、「スタック」ってよく聞くけど、何ですか?

いい質問だね。スタックっていうのは、つまり「積み重ねる」という意味の英単語で、データが積み重なる様子を表しています。イメージとしては、給食当番が食べ終わったお皿を重ねていくでしょ?最初に置いたお皿は一番下で、最後に置いたお皿が一番上。食べるときは上から順番に取っていく。その仕組みをデータにも使おう、ということなんですよ。
あ、でもお皿って別に上から取らなくてもいいんじゃ…?

そうだね。現実のお皿はね。でも、コンピュータが処理する数字やデータを整理するときには、ルールを決めた方が便利なんです。「後から入ってきたものから順番に処理する」っていうルールを決めると、プログラムがシンプルに書けたり、間違いが減ったりするんですよ。このルールのことをLIFO(後入先出)って呼びます。つまり「最後に入ったものが最初に出てくる」ってことですね。
あ、なるほど。でもそんなルール、実際に使うことあるんですか?

めちゃくちゃ使うんです。例えば、あなたがアプリで何か操作して「あ、間違えた」って「戻る」ボタンを押したことありますね?その「戻る」機能はスタックで実現されているんですよ。最後にやったことから順番に『undo』してくから、スタックなんです。他にも、ゲームのマップを探索するときとか、関数の呼び出し順序を管理するときとか、本当にいろいろな場面で使われてるんですよ。
へー!そんなに身近にあるんだ!それって、プログラマーが難しく考えてるから「スタック」って名前を付けてるだけですか?

鋭いね。そこなんです。「お皿を積む」って日本語で言えばいいのに、わざわざ「スタック」って英語で言うのは、コンピュータの中身を説明するときの共通ルールだから。世界中のプログラマーが同じ言葉を使うから、意思疎通がスムーズになるんですよ。難しく見えるのは、専門用語を使ってるからで、本質は超シンプルなんです。
📝 3行でまとめると
  1. スタックは「後から入ったものから先に処理する」というLIFOのデータ構造で、お皿を積み重ねるのと同じ仕組みです
  2. スマホのアプリの「戻る」機能やゲームのマップ探索など、日常的にたくさんの場面で使われている重要な概念です
  3. むずかしく聞こえますが、実は「最後に追加したものから順番に取り出す」というシンプルなルールなだけです
目次

もうちょっと詳しく

スタックというのは、データ構造(つまり、データを整理して保管する方法)の一種です。具体的には、データを一列に並べるのではなく、後から追加したものが手前に来るように重ねていく方法です。たとえば、図書館で返却期限の近い本から順番に読もうと思ったときに、デスクの横に積み重ねていったら、一番最後に置いた本(つまり一番上)が一番手前にあって、一番先に置いた本(一番下)が一番奥にあります。この状態で本を読むときは、一番上の本(最後に置いた本)から読んでいきますよね。それがスタックです。コンピュータの世界では、このシンプルな仕組みを使って、いろいろな複雑な処理を実現しているんです。

💡 ポイント
スタック=最後に追加したものが最初に出てくる。つまり後入先出(LIFO)です

⚠️ よくある勘違い

❌ 「スタックは難しいプログラミングの技術で、初心者には関係ない」
→ 実はあなたが毎日使ってるアプリの中に隠れています。「戻る」「元に戻す」はすべてスタックなんです
⭕ 「スタックは、最後に入ったものから先に処理する、とてもシンプルなルール」
→ シンプルだからこそ、いろいろな場面で活躍しているんです。複雑に見える機能も、実はスタックを組み合わせて実現されていることが多いです
なるほど〜、あーそういうことか!

[toc]

スタックって、結局なんなの?

スタックを理解するために、まず「データ構造」という言葉から説明しましょう。データ構造というのは、つまり「情報をどういう形で保管して整理するか」という方法のことです。家に荷物を片付けるときに、いろいろな方法がありますよね。押し入れに整列して並べたり、引き出しに分けて入れたり、一箱に全部放り込んだり。同じように、コンピュータの中のデータも、どうやって保管するかで方法が違うんです。その方法のひとつがスタックというわけです。

スタックの基本的な特徴は、「最後に追加したデータが最初に取り出される」という点です。これをLIFO(Last In First Out)と呼びます。「最後に入ったのが最初に出てくる」ってことですね。現実の世界でこれに一番近いのは、給食当番が積み重ねたお皿です。朝、お皿を積み始めたときの一番下のお皿は、全部積み終わった後は一番下にあります。そして、誰かがお皿を取るときは、一番上から取りますよね。だから最後に積んだお皿が最初に取られていきます。これがスタックです。

もう一つの例え話をしましょう。あなたが電車で通勤・通学するときのことを考えてください。駅の改札を通るときに、多くの人が一列に並んでいます。改札機の中には、電車の切符を読み込むセンサーがあります。では、コンピュータがその日の「改札を通った人の記録」を保管するときに、最後に通った人の情報から遡りたいなら?スタックで保管するのが便利です。最後に通った人の情報が一番上にあるから、すぐに取り出せます。このように、「最新の情報から必要」という場面では、スタックが活躍するんです。

プログラミングでスタックを使うと、コードがシンプルに書けます。なぜなら、「後から来たものから処理する」というルールが決まっているから、余計なことを考えなくていいんです。余計な指示を書かなくていいから、バグも減ります。だから、プログラマーはスタックをよく使うんですよ。

スタックが活躍する場面①:「戻る」機能

あなたがスマートフォンのアプリを使っているときに、「あ、ここじゃない」と思って「戻る」ボタンを押すことってありますよね。例えば、SNSアプリで友達のプロフィールを見に行ったけど、やっぱりタイムラインに戻りたい。そんなときに、戻るボタンを1回押せば、一つ前の画面に戻ります。さらに戻りたければもう一回押す。この仕組みがスタックで実現されているんです。

具体的に説明します。あなたがアプリを使っている流れを想像してください。まず「ホーム画面」を見ています。次に「友達のプロフィール」をタップして、その画面に移ります。次に「友達のフォトアルバム」をタップして、そっちの画面に移ります。この流れをスタックに記録すると、こんな感じになります。

一番下から順に:ホーム画面 → 友達のプロフィール → フォトアルバム という感じで積み重なります。では、戻るボタンを押すと?一番上の「フォトアルバム」が取り出されて、その下の「友達のプロフィール」が表示されます。もう一回戻ると、今度は「友達のプロフィール」が取り出されて、「ホーム画面」が表示されます。このシンプルな仕組みで、「戻る」機能が実現されているんです。

もし、スタックを使わず、「戻った画面の一覧」を別に保管したら?その管理が大変になりますよね。スタックなら「最後に追加したものから順番に取り出す」というシンプルなルールで全部OK。だから、ほとんどすべてのアプリが「戻る」機能を実現するのにスタックを使っているんです。つまり、あなたがスマホを使う度に、スタックの恩恵を受けているってわけです。

スタックが活躍する場面②:ゲームのマップ探索

ゲームをしていると、迷路のようなマップを探索することってありますよね。ダンジョン系のゲームなら、いろいろな道が分かれていて、どっちに行ったら宝物があるのか、探さないといけません。では、コンピュータがこんな「どこに何があるか」を効率よく探索するときに、スタックが活躍するんです。

具体的には、ゲームの画面の「今いる場所」をスタックに記録していきます。あなたがゲーム内で移動するたびに、「今ここに来た」という情報を上に乗せていきます。そして、もし袋小路(どこにも繋がっていない道)に着いたら?来た道を戻ります。スタックの一番上の情報を取り出すことで、「一つ前にいた場所」に戻るんです。このシンプルなルールで、複雑な迷路でも全部探索できます。

こういう探索方法を「深さ優先探索」(つまり、一本道を最後まで行ってみて、ダメなら戻ってくる)と呼びます。スタックを使うと、この「戻る」という動きが自動的に実現されるんです。だから、ゲーム開発者も迷路生成プログラムの製作者も、スタックを使っているわけですね。

スタックが活躍する場面③:関数の呼び出し

プログラミングで「関数」という概念があります。関数というのは、つまり「やることを一まとめにしたプログラム」という意味です。例えば「ユーザーの名前を表示する関数」とか「計算を行う関数」とか。で、ときには関数の中から別の関数を呼び出すことがあります。AさんのプログラムはBさんのプログラムを呼び出して、BさんのプログラムはCさんのプログラムを呼び出して…という感じですね。

こういう「どの関数からどの関数が呼ばれたか」という流れを管理するのに、スタックが使われます。例えば、メインプログラムから関数Aを呼び出したら、「メインプログラムが呼び出し元」という情報をスタックに乗せます。関数Aから関数Bを呼び出したら、「関数Aが呼び出し元」という情報を上に乗せます。関数Bから関数Cを呼び出したら、「関数Bが呼び出し元」という情報を上に乗せます。

では、関数Cが処理を終わったら?スタックの一番上「関数Bが呼び出し元」という情報を取り出して、関数Bに戻ります。関数Bが終わったら、「関数Aが呼び出し元」を取り出して関数Aに戻る。こうやって、複雑に入り組んだ関数の呼び出し関係を管理しているんです。これが「コールスタック」と呼ばれるやつで、プログラム実行の生命線ともいえます。

スタックと似てるやつ:キューとの違い

スタックと似ているけど違う、という概念に「キュー」があります。キューは、つまり「先に入ったものが先に出てくる」という方式です。FIFO(First In First Out)と呼びます。現実の世界でいえば、スーパーのレジに並ぶのと同じ。先に並んだ人が先に会計されます。スタックはお皿の積み重ね(後から積んだのが最初に取られる)ですが、キューはレジの列(先に来た人が先に進む)なんです。

では、どうやって使い分けるか?「戻る」機能や「やり直す」機能が必要な場面ではスタック。「順番に処理していく」という場面ではキューを使います。例えば、プリンタに複数の人が印刷を指示したら、スタックで管理しちゃダメです。最後に指示した人の印刷が最初に出てきちゃいます。ちゃんとキューで管理して、先に指示した人から順番に印刷するんです。

つまり、「どっちがいい」ではなく、「何をしたいか」で選ぶものなんですね。スタックは「最新の情報が必要」な場面で、キューは「順番に処理したい」場面で活躍するんです。

実際のプログラミングでスタックを使う

では、実際にプログラミングでスタックを使うときって、どうやるんでしょう?プログラミング言語によって、スタックが組み込まれていたり、自分で作らないといけなかったりします。でも、考え方は同じです。「データを追加する」「一番上のデータを取り出す」という2つの動作ができれば、スタックです。

例えば、Pythonというプログラミング言語なら、リスト(つまり、複数のデータを入れるための箱)を使ってスタックを実現できます。データを追加するときは「append(追加する)」という命令を、データを取り出すときは「pop(取り出す)」という命令を使います。すると自動的に、後から追加したデータが最初に取り出されます。

Javaなら「Stack」というクラス(つまり、スタック用に用意された道具)が最初から用意されてます。C言語なら、自分でスタックの仕組みを作る必要があります。でも、考え方はどれも同じ。「後から入ったものから出す」というシンプルなルールを実装してるだけなんです。

大切なのは「どのプログラミング言語を使うか」ではなく、「どういう場面でスタックが便利なのか」を理解することです。その場面がわかれば、どの言語でも実装できるようになります。

💡 こっちの記事も参考になるよ
テックスタックって何?わかりやすく解説
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

大人になってから「これ知らなかった…」と恥ずかしい思いをした経験から、このサイトを作りました。お金・仕事・社会のしくみって、学校で教えてくれないのに知らないと損することだらけ。むずかしい言葉を「あーそういうことか!」って思えるまでかみ砕いて説明するのが得意です。主に経済・法律・税金・ライフイベント周りの用語を毎日更新中。

目次