View on GitHub

SSR C11 Textbook

はじめに

Back to the ToC


なぜプログラミング言語を使うのか

私たちが普段日常会話で使っている日本語や英語などは,自然言語と呼ばれる言語です. 一方で,世の中のほとんどの機械(計算機)は, 自然言語では動きません. 深層学習によって一部の機械では,自然言語による動作が実現されつつありますが,現在はごく一部の例であると言えるでしょう. 人には人のための自然言語があるように,機械には機械のための機械語があります.

それでは,我々が機械語を話せば良いのでしょうか? 百聞は一見に如かずです. 機械語の一例を見てみましょう.

:020000040000FA
:1000000058210020150200001D0200001F02000000
:100010002102000023020000250200000000000071
:1000200000000000000000000000000027020000A7
:1000300029020000000000002B0200002D02000039
:10004000A10200002F020000ED0500002F020000B9
:100050002F0200002F0200002F0200002F020000DC
:100060002F0200002F0200002F0200002F020000CC
:100070002F0200002F0200002F0200002F020000BC
:100080002F020000F90200002F0200002F020000E2

(……まだまだ続きます)

これはhexと呼ばれる形式の機械語の一種であり,マイコンでLEDを点滅させるだけの簡単なプログラムです. 機械語自体も広義ではプログラミング言語の一種でありますが,低水準言語と呼ばれ,一般にプログラミング言語と呼称される言語とは全くと言っていいほど異なります. これを解読しようという気持ちには,なかなかならないでしょう.

計算機が誕生した直後の技術者や研究者は,このような機械語を直接読み書きしてプログラミングを行っていたそうです. しかし機械語を直接読み書きすることには,効率が悪い,専門家でないとわからない,といった問題がありました. 残念ながら,自然言語は機械に優しくなく,機械語は人に優しくありません. そこで,人間が扱いやすく,機械を動かすことのできる言語として,1957年にIBMが世界初の高水準なプログラミング言語FORTRANをリリースしました. 以降今日まで,多くの高水準言語が作られています. 21世紀において使われている高水準言語は,人と機械が対話をするために欠かせない道具なのです.

高水準なプログラミング言語の登場した意義はこれだけではありません. 計算機の発明以降,計算機の種類が増えるにしたがって,計算機ごとに機械語が違うといった問題も生じていきます. 自然言語でいえば,方言のようなものでしょうか. 今でも,A社が作るCPUが扱える機械語と,B社が作るCPUが扱える機械語が違うことは,よくあります. 一方で,プログラマからすれば,どの計算機でも,同じプログラムでは同じ処理をしてほしいものです. 高水準な言語は,機械語と違うからこそ,どの計算機に対しても同じ書き方をすることができ,ソフトウェアの開発を今でも支えているのです.

機械語には機械語独特の面白さがありますし,現代においても機械語の研究開発は継続して行われています. 一方で,本書の読者の多くは「プログラムの仕組みを学びたい人」よりも「プログラムを使って何かをしたい人」でしょう. もちろん「プログラムの仕組みを学ぶ」ことにも価値はあります. しかし多くの場合,「プログラムを使って何かをする」過程で必ず「プログラムの仕組みを学ぶ」必要が出てくるものです. したがって,「プログラムを使って何かをしたい」人は,基本的にはプログラムを使って何かをするべきです. 目的と手段が入れ替わらないようご留意いただきたいと思います.

プログラミング言語の分類

ここでは,広い意味でのプログラミング言語を分類して紹介します. どれをプログラミング言語と呼ぶかや,分類方法については多くの説がありますが,ここでは一例を紹介します.

以下の内容はあくまでも,著者が最低限必要と考えた,基礎的かつ大局的な話です. 詳細に興味のある方は,是非色々と調べてみてください.

低水準言語(低級言語)

機械語や,ほとんど機械語に近いような言語のことを,低水準言語または低級言語 (low-level programming language) と呼びます. ほとんど機械語に近い言語としては,アセンブリ言語 (assembly language) が挙げられます.

機械にとっては扱いやすい一方で,人間が直接記述するには向きません. また,CPUの種類に応じて言語や文法が異なることが多いです. 具体的には,A社製のCPUを動かすための機械語(アセンブリ言語)と,B社製のCPUを動かすための機械語(アセンブリ言語)が違うといったことがよく起こります.

高水準言語(高級言語)

世の中で一般的にプログラミング言語と呼ばれているものは,高水準言語または高級言語 (high-level programming language) に該当します. 高水準言語は,私たち人間が扱いやすいように設計されており,またCPUの種類にも依存しないように作られています. 逆に言うと,機械から見たら扱いにくい,あるいは扱うことのできない言語でもあります. このため,何らかの方法で高水準言語は,機械にわかりやすい形,すなわち低水準言語に変換する必要があります. 各言語で得意とすることが異なります.

高水準言語を低水準言語に変換する方法は多く存在しますが,大別するとコンパイラによる方法と,インタプリタによる方法に分類されます. コンパイルもインタープリトも,高水準言語を機械語に変換する操作ですが,翻訳するタイミングが異なり,付随する性質も変わります. 近年では両者の境界に存在するような方式もできていますが,本書では扱いません.

またパラダイムと呼ばれる,いわばプログラミング言語の設計コンセプトのようなものでも分類されることがあります.

コンパイル方式

本書で扱うC言語はこれに該当します. プログラム実行前に,コンパイラというアプリケーションによるコンパイル(翻訳)という操作が必要になります. そして,コンパイルによって生成された低水準言語を実行することで,プログラムが動くという仕組みです.

インタープリト方式と比較して,実行速度が速い利点があります. またコンパイルによって,一部のバグをプログラム実行前に検出することが期待されます.

C言語の主要なコンパイラであるGCCの動作については,本書の応用編にて解説します.

インタープリト型

スクリプト言語と呼ばれことも多いです. インタープリタというアプリケーションが,書かれたプログラムを1〜数行単位ずつ低水準言語としてインタプリト(解釈)し,生成された低水準言語逐次的に実行します. コンパイルのような事前処理を必要としませんが,その分実行時間が長くなる傾向にあります.

コンパイル方式と比較して,気軽に実行ができる利点があります. その気軽さからユーザ人口が多く,ライブラリや知見が豊富になりやすい特徴もあります.

中間言語

プログラミング言語に関連して,中間言語 (intermediate language, IL) }というものも紹介しておきます. 高水準言語をコンパイルする際に,直接低水準言語を生成するのではなく,中間的な表現への翻訳を挟む場合があります. この中間的な表現が言語として成り立っているとき,中間言語と呼ばれます. 中間言語を生成する高水準言語としては,JavaやC#が代表的です.

高水準言語のコンパイル時に生じることがほとんどで,人が読み書きをすることは多くありません.

例えばドイツ語とフランス語を,日本語と中国語と韓国語に翻訳することを考えましょう. 直接翻訳しようとすると,2かける3で合計6組の翻訳機が必要になります. ここで,中間言語として英語を導入すると,ドイツ語とフランス語を一度英語に翻訳し,その英語を日本語・中国語・韓国語に翻訳すればよくなります. すると,なんと翻訳機の数は5組でよくなります. これが中間言語の存在意義と言えるでしょう.

C言語

C言語は1972年にベル研究所が作成した言語で,計算機の黎明期より盛んに使われてきました. 今日の高水準言語と比較すると,標準機能は必要最低限に近いものとなっています.

今回扱っているC11 (ISO/IEC 9899:2011)は,本書の執筆が始まった2017年春時点で最新の規格でした. 現在はC17 (ISO/IEC 9899:2018)がリリースされており,これが最新の規格となっています. C言語の標準化された規格としては,C89/90,C99,C11,C18が存在します.

C言語の今

現在C言語は主にマイコンやOS等のレイヤが低い(≒機械に近い)部分で多く使われています. 新しい言語への置き換えが進んでいると言う意味で,C言語が今後発展することはほぼないでしょう. 特に組み込みの分野では,C言語(ないしC++)が主流であり,PIC,ARM,STM等のマイコンはC言語での開発を主としています.

どうしてC言語?

これは多くの場において何度も議論されてきました. ここでは著者の見解を述べたいと思います.

結論から言えば,はじめて触るプログラミング言語は何でも良いのです.

プログラミングを学ぶ事の本質は,言語の仕様に精通することではありません. プログラムを使って何かをするために必要なデータ構造アルゴリズムと呼ばれる知識を付けることです.

「じゃあ流行りのPythonでいいじゃないか!」「確実にその方が役に立つじゃないか!」という意見を,何年も受けてきました. しかしそれでもなおC言語を扱うのには,理由があります. C言語でしかできないこと,C言語でしか学べないことがあるからです.

本研究会の活動においてソフトウェアに携わる以上,マイコンやOSと対話するべき日がいつかやってきます. もしロボット関連をやるのであればすぐにやってきます. そのとき,C言語の知識が必ず要求されます. 計算機が発展した現代では,講習会でもしなければC言語に触れる機会はそうそうないでしょう. C言語を講習会で扱うのは,来たるべき日のためなのです.

ここまで書いたC言語でできることは,実はC++でもおよそ同様に使うことができます. 最初からC++をやらずにC言語をやる理由は,C言語の方がシンプルだからです. 逆に言うと,C言語が一度書けるようになったときには,C++を学ぶハードルは大きく下がっていることしょう.


Back to the ToC

Next: プログラムの実行


(c) 2017-2021 Yuki Onishi