C言語 〜メモリを直接触らせてやる。だが、ミスしたらPCごと死ね〜

2026-11-04 / シリーズ「言語の履歴書」第1話

📄 本日の履歴書:C(シー)

氏名: C(シー)
生年月日: 1972年(現役54歳)
出身地: アメリカ・ニュージャージー州 ベル研究所
生みの親: デニス・リッチー、ケン・トンプソン
現住所: 世界中のパソコン・スマホ・ゲーム機・車・家電の最深部(OSカーネル)
性格: 超頑固、極限まで無口、不親切、一切妥協しない絶対的リアリスト
座右の銘: 「プログラマーを信じろ。プログラマーの邪魔をするな」
得意技: メモリ(物理番地)の直接解剖、ナノ秒単位の爆速実行
弱点: タイプミス1文字でOS全体を道連れにして爆死すること

1. 素朴な疑問:なぜ令和の時代に「50年前の化石」を学ぶの?

ようこそ。俺の名前は「C」だ。

今どきのプログラミング入門といえば、「PythonでAIを作ろう!」「JavaScriptでWebアプリを作ろう!」といったキラキラした言葉が並んでいるよな。 画面には親切なエラーメッセージが出て、スペルを間違えても「ここが違いますよ」と教えてくれる。

そんな時代に、情報系の大学や企業の新人研修に行くと、いまだに黒い画面を開かされ、

「まずC言語を学びなさい。ポインタを理解しなさい」 と分厚い教科書を渡される。

お前たちは心底ウンザリして、こう叫びたくなるはずだ。

「なぜ!? 1972年生まれって、半世紀以上前のおじいちゃん言語じゃないか! なんでわざわざ書きづらくて不親切な化石を勉強しなきゃいけないんだ? Pythonだけじゃダメなのか!?」

いい疑問だ。 だが、その疑問に答える前に、ひとつ残酷な現実を教えてやろう。

お前が今使っているiPhoneの「iOS」も、Windows 11も、世界中のWebサーバーを動かすLinuxも、PlayStation 5のOSも、Pythonという言語の処理系(CPython)そのものも―― すべて、俺(C言語 / C++)の肉体で書かれている。

もし世界から俺が書いたプログラムを一瞬で消し去ったらどうなるか? 世界中のパソコンとスマホは画面が真っ暗になって二度と起動せず、新幹線も飛行機も止まり、銀行のATMは沈黙し、世界経済は1960年代へ逆戻りする。

なぜ、無数の新しい言語が生まれては消えていった半世紀の間、誰も俺を王座から引きずり降ろせなかったのか? その秘密を、俺自身の言葉で教えてやる。


2. 誕生の歴史:人間が読める「アセンブラ(機械の直通電話)」が欲しかった

時計の針を、1970年代初頭のベル研究所に戻そう。 当時、俺の親父であるデニス・リッチーとケン・トンプソンは、第7話で学んだ伝説のOS**「UNIX(ユニックス)」**を作っていた。

1973年のケン・トンプソンとデニス・リッチー
俺の生みの親、ケン・トンプソン(左)とデニス・リッチー(右)。1973年、ベル研究所でUNIXとCを育てていた頃の2人。写真:作者不詳(パブリックドメイン/Wikimedia Commons)

当時のコンピュータの世界には、まともな言語がなかった。 OSのような基本ソフトを書くには、CPUに直接「レジスタAに数字を入れろ」「番地300へジャンプしろ」と命令する**「アセンブリ言語(機械語と1対1の暗号)」**を手書きするしかなかったんだ。

😱 1970年代初頭の絶望:アセンブリ言語(機械語直結) 『MOV EAX, [EBX+4]』 ・人間が読むと発狂する難しさ ・CPUの種類が変わるたびにゼロから全部書き直し! 人間が読める言葉で、機械を直接操りたい! 👑 救世主:C言語の誕生(1972年) 『*p = 10;』 ・人間が英語っぽく読める(高級言語) ・なのに、裏では機械語とまったく同じメモリ操作ができる! ・別のCPUにもコンパイル一発で移植できる!

アセンブリ言語は最悪だった。 CPUの型番が変わるたびに、何万行ものOSのコードをゼロから全部書き直さなければならなかったからだ。

そこで親父たちは考えた。 「人間が英語の数式のようにスラスラ読めて、別のコンピュータにも簡単に持っていける(移植性がある)言語を作ろう。ただし、ハードウェアのメモリやCPUを直接いじくり回せる『アセンブラ並みの暴力的な自由』は1ミリも手放さないぞ!」

そうして生まれたのが、俺――「C言語」だ。 俺は「高級言語(人間に優しい言語)」の顔をして生まれたが、その皮を1枚めくれば、**「ハードウェアの電線を素手で掴んで火花を散らすアセンブラそのもの」**だった。

親父たちは、生まれたばかりの俺を使って、UNIXのOSの大部分をC言語で書き直してしまった。 世界で初めて**「人間の読める言葉で書かれたOS」**が誕生した瞬間だった。ここから現代のITの歴史が始まったんだ。

ミニコンピュータ PDP-11/70 の実機
UNIXとCが育ったミニコンピュータ PDP-11/70。ランプとスイッチが並ぶ前面パネルが、当時の「機械と直接対話する」開発の姿を物語る。写真:Joe Mabel(CC BY-SA 3.0/Wikimedia Commons)

3. 最大のトラウマ:「ポインタ」という名の神のメス

プログラミング初心者が俺の門を叩き、9割が涙を流して挫折していく関門。 それが**「ポインタ(Pointer)」**だ。

PythonやJavaScriptしか触ったことがないヤツは、変数を「魔法の宝箱」だと思っている。 x = 10 と書けば、箱の中に10が入る。その箱がパソコンのどこにあるかなんて、考えたこともないだろう。

だが、俺の世界に変数の箱なんて生ぬるいファンタジーは存在しない。 第1話で学んだことを思い出せ。 パソコンの中にあるのは、**「0番地から何十億番地まで、1バイトごとに番号が刻印された広大なメモリのロッカー室」**だけだ。

俺はお前に、そのロッカーの**「本物の物理的な部屋番号(番地 / アドレス)」**をそのまま渡す。 これがポインタだ。

📝 ポインタ変数 p 中身: 『0x7FFF0001』 (xの部屋番号そのもの!) 番地: 0x7FFF0001 中身のデータ: 10 「*p = 20」と命令すると… 部屋番号を直接襲撃して中身を書き換える!
int x = 10;     // ロッカーのどこかに「10」を入れる
int *p = &x;    // pという紙に、xが入っている「本当のロッカー番号」をメモする
*p = 20;        // そのロッカー番号を直接ノックして、中身を「20」に書き換える!

触って試す:ポインタを辿る体験

🧭 ポインタを辿る体験

メモリのロッカー室です。番地0x1000の部屋に変数 x、番地0x1004の部屋にポインタ p がいます。p の中身は「0x1000」、つまり x の番地です。下のボタンを押して、x・&x・p・*p の違いを確かめてください。

番地 0x1000
変数 x の部屋
10
番地 0x1004
ポインタ p の部屋
0x1000

まずはボタンを押してみてください。

なぜ他の言語はポインタを隠したのか?

現代の言語(Java、Python、Ruby、Goなど)は、お前たちからポインタを取り上げ、決して触らせないように厳重に隠している。 なぜか?

危険すぎるからだ。

ポインタを使えば、神のような自由が手に入る。 画面のピクセル(第5話)が並ぶビデオメモリの番地を直接指定して0.00001秒で色を塗りつぶすこともできるし、OSの心臓部(第6話)を直接書き換えることもできる。余計な仲介者がいないから、スピードは極限まで速い。

だが、もしお前が寝ぼけてタイピングミスをし、存在しない番地や、OSの大事な心臓部が入っている番地を *p = 0; と書き換えてしまったらどうなるか?

プログラマーがポインタの計算を1文字ミスる! 存在しないメモリ番地(NULL)や 他人の部屋(OSの領域)を強襲! 💥 Segmentation Fault(不正メモリアクセス)! 保護違反でプログラムが即座に射殺・強制終了!

OSが血相を変えて飛んできて、**「貴様! 人の部屋を土足で荒らすな!」とお前のプログラムを射殺する。 これが、全C言語プログラマーが夜中にうなされる悪夢のエラー「Segmentation Fault(セグフォ / コアダンプ)」**だ。

第16話で学んだ「バッファオーバーフロー攻撃」も、俺がプログラマーを信じて「枠をはみ出してメモリを書き換える自由」を与えすぎたせいで起きた悲劇だ。 俺はお前に**「外科手術の神のメス」**を渡している。 患者の命を救うのもお前次第だが、メスを取り落として自分の太ももを突き刺して死ぬのもお前の自由だ。俺はお前の手元を決して止めない。


4. 物理の掟:なぜ最新言語でも「OSやゲームの心臓」を奪えないのか?

「危なくて難しいなら、全部PythonやJavaに置き換えればいいじゃないか!」 そう思うだろう? だが、それは物理的に絶対に不可能なんだ。

その理由を理解するためのキーワードが、現代言語が誇る便利機能**「ガベージコレクション(GC / 自動ゴミ掃除)」**だ。

ガベージコレクションという「時限爆弾」

PythonやJava、JavaScriptは親切だ。 お前がメモリを使い終わったら、裏で「お掃除ロボット(GC)」が勝手に巡回して、使わなくなったメモリを掃除してくれる。プログラマーはメモリの破棄を考えなくていい。

だが、タダ飯はこの世に存在しない。 このお掃除ロボットには、致命的な物理の代償がある。 部屋を本格的に片付ける瞬間、ロボットは**「部屋にいる全員の動きを一時停止(Stop The World)」**させるんだ。

🧹 現代言語(Java / Go / Python等:ガベージコレクション) プログラムが快調に動作中 🗑️ メモリのゴミが溜まってきた! お掃除ロボット(GC)が発動! 🛑 全員ストップ!(Stop The World) 掃除が終わるまでの数ミリ秒〜数十ミリ秒、プログラム全体がフリーズ! ⚙️ C言語(職人の手動管理:malloc / free) メモリが必要なときに自分で確保(malloc)し、 いらなくなったら自分で即座に捨てる(free) ✨ お掃除ロボットなんていない! 1ミリ秒の停止もなく、常に一定速度で爆走し続ける!

普通のWebサイトや事務用アプリなら、0.01秒くらい画面が止まっても誰も気づかない。 だが、以下の現場でお掃除ロボットが発動して「0.01秒フリーズ」したら何が起きるか想像してみろ。

  • 時速300kmの新幹線や自動車の自動ブレーキ:0.01秒の停止で数十メートル滑走して衝突事故になる。
  • 心臓のペースメーカーや人工呼吸器:0.01秒の停止が患者の死に直結する。
  • PlayStation 5の超大作アクションゲーム:1秒に60フレーム(0.016秒に1回)画面を描き替えている最中にGCが発動すれば、画面がカクついてゲーマーが激怒する。
  • OSのカーネル(第6話):OS自身がお掃除ロボットで停止したら、パソコンの上で動いているすべてのアプリが巻き添えでフリーズする。

俺(C言語)には、お掃除ロボットなんてお節介な奴はいない。 メモリを確保するのも自分(malloc)、片付けるのも自分(free)。 面倒で、忘れるとメモリリーク(メモリのゴミ屋敷化)を引き起こすが、その代わり**「いつ、どの命令が、何ナノ秒で終わるか」が100%完全に予測できる(決定論的動作)**。

この「寸分の狂いも許されない極限の世界」において、俺の代わりを務められる言語は、この半世紀の間、地球上にただの1つも存在しなかったんだ。


5. 後継者たちとの関係:Rustの台頭と「老兵の誇り」

もちろん、俺も自分が完璧だとは思っていない。 俺があまりにも安全確認をプログラマーに丸投げしすぎたせいで、世界中でセキュリティホールが生まれ、何兆円もの損害が出たのは事実だ。

だから、俺の血を引く子どもやライバルたちがたくさん生まれた。

  • C++(1985年生まれ):俺の爆速性能を受け継ぎつつ、「オブジェクト指向」という武器を身につけた俺の息子だ。巨大なゲームエンジン(Unreal Engine)や金融の超高速自動取引は、こいつが仕切っている。
  • Java / C#(1990年代生まれ):俺のポインタの危険さに恐怖し、安全な檻(仮想マシン)の中で動くように作られた優等生たちだ。
  • Rust(2010年生まれ):今、俺の最大のライバルとして注目されている新星だ。「ポインタの直接操作と同じスピードを出しつつ、コンパイルの段階でメモリの間違いを100%弾く」という恐るべき知能を持っている。Linuxカーネルの一部にも採用され始めた。

「じゃあ、いよいよC言語もお役御免か?」 フッ、若い奴らはそう言いたがる。

だが、Rustのコンパイラ自身を一番下の機械語に変換している土台(LLVM)は何で書かれていると思う? 世界中のあらゆるマイコン(炊飯器やエアコンに入っている数十円の小さなコンピュータチップ)を動かすための最小の開発環境は、誰のために用意されていると思う?

すべて俺だ。 ハードウェアという「金属とシリコンの冷たい板」が存在し続ける限り、その金属の熱を一番肌で感じながら直接対話できる言語は、これからも俺をおいて他にない。


📝 3行で頭に入る「試験・実務の要点まとめ」

  • C言語の歴史と位置づけ:1972年にUNIXを記述するために開発された。ハードウェアを直接制御できる低水準な操作性と、機種依存しない移植性を兼ね備え、現代のOSや組み込みシステムの基盤となっている。
  • ポインタとメモリ管理:変数の値ではなくメモリ上の所在番地(アドレス)を保持する変数をポインタと呼ぶ。malloc/freeによる動的メモリ管理が可能だが、解放漏れ(メモリリーク)や不正アクセス(バッファオーバーフロー)のリスクを伴う。
  • GCを持たない強み:ガベージコレクションによる実行時の一時停止(Stop The World)が存在しないため、**決定論的なリアルタイム処理(OSカーネル、ゲームエンジン、ハードウェア制御)**において代替不可能な優位性を持つ。

確認クイズ

📝 確認クイズ(3問)