●はじめに

 今回から,Javaのプログラミング・スタイルの説明を始めます。Javaは,新しいプログラミング言語ですが,C++(シー・プラス・プラス)というプログラミング言語をベースとして開発されています。C++は,C言語(シーげんご)というプログラミング言語に機能を追加したものです。C言語やC++の知識は,Javaを理解する上で,大いに役立ちます。そこで今回は,C言語やC++のお話をしたいと思います。

●C言語からC++へ,C++からJavaへ

図1●C言語、C++,およびJavaの関係
 C言語は,UNIXというオペレーティング・システムを記述するためのプログラミング言語として開発されました。C言語の特徴は,アセンブラ(コンピュータのプロセッサに与える命令を記述するプログラミング言語)に匹敵するほど細かな制御が可能だということです。「C言語を使えば,どんなプログラムでも記述できそうだ」ということで,C言語は広く普及しました。

 しかし,C言語にもできないことがありました。それは,大規模なプログラムで要求されるオブジェクト指向プログラミング(プログラムを「物」の集合体として作成する技法)です。時代の流れとともに,プログラムが肥大化かつ複雑化するにつれ,オブジェクト指向プログラミングが求められてきました。そこで,C言語にオブジェクト指向プログラミングを可能とする機能を追加するという形で,C++が開発されました。従って,C++はC言語と上位互換性があります。

 Javaを開発したグリーン・プロジェクトでは,プログラミング言語としてC++を採用することを検討していた時期があったそうです。しかし,C++をそのまま採用するにはいくつかの問題点がありました。そこで,C++をベースとして,不要な機能は削除し,不足していた機能は追加するという形で,新たにJavaを開発したのです(図1[拡大表示])。

 では,C言語ではできなかったオブジェクト指向プログラミングが,なぜC++で可能になったのでしょうか? C++には,どんな問題点があり,それをJavaがどうやって改善したのでしょうか? 順番に説明しましょう。

●関数と変数から構成されたC言語のプログラム

リスト1●C言語のプログラムの例
 どのようなプログラミング言語を使用したとしても,プログラムの内容は処理とデータから構成されるものとなります。C言語では,処理を関数で表わし,データを変数で表します。リスト1[拡大表示]に,C言語で記述されたプログラムの例を示します。このプログラムは,何らかの商品管理システムの一部だと思ってください。Shohinmei,Tanka,Zaikoは,商品名,単価,在庫を表わす変数で,ShowDataは変数の値を表示する関数です。

 関数には,C言語が標準関数ライブラリ(作成済みの関数セット)として提供しているものと,プログラマが独自に作成するものがあります。printfは標準関数ライブラリとして提供されているもので,ShowDataは独自に作成したものです。リスト1の内容は,何となく分かればOKです。

●C言語の構造体

リスト2●C言語の構造体の例
 C言語で大規模なプログラムを作成すると,膨大な数の関数と変数が羅列されたものとなります。数千~数万の関数と変数から構成されたプログラムを思い浮かべてみてください。それが,いかに複雑であるかは,容易に想像できることでしょう。複雑なプログラムは,必然的に開発効率が悪いものとなります。

 C言語には,複数の変数をまとめて整理できる構造体(こうぞうたい)という機能があります。リスト2[拡大表示]に,構造体の例を示します。これは,リスト1の中にある3つの変数をまとめてShohinJoho(商品情報)という名前を付けたものです。構造体は,structというキーワードで表わされます。構造体を使えば,プログラムの複雑さを少しだけ緩和できます。しかし,関数を整理することはできないので,完璧とは言えません。

●C++はC言語に機能を追加したプログラミング言語である

リスト3●C++のクラスの例
 C++では,C言語の構造体の機能を拡張して,「クラス」を作成できるようにしました。クラスは,複数の関数と変数をまとめて整理できるものです。リスト3[拡大表示]に,クラスの例を示します。これは,リスト1の中にある3つの変数と1つの関数をまとめてShohin(商品)という名前を付けたものです。クラスは,classというキーワードで表わされます。

●クラスによるオブジェクト指向プログラミングの実現

 次回の講座で詳しく説明しますが,オブジェクト指向プログラミングとは,プログラムを物(オブジェクト)の集合体として整理し,効率的に作成する手法です。物は,「動作」と「属性」を持つものとして定義されます。C言語やC++では,動作は関数であり,属性は変数です。従って,関数と変数をまとめたクラスは,物(オブジェクト)を定義するものとなります。クラスを作成する機能によって,C++ではオブジェクト指向プログラミングが可能となったのです(図2[拡大表示])。

●C言語とC++の問題点

図2 プログラムをクラスの集合体として整理する
 C言語とC++をマスターすれば,Javaを使う必要などないと思われてしまうかもしれません。しかし,C言語とC++にはいくつかの問題点があります。

 C言語に機能を追加した形で開発されたC++では,クラスを使っても使わなくても構いません。中途半端なオブジェクト指向プログラミングも可能です。「オブジェクト指向プログラミングするぞ!」という意気込みがないと,C++ではオブジェクト指向プログラミングができません。ついつい,単独の変数や関数を使う誘惑に負けてしまうことがあります。

 C言語やC++の特徴の1つに,ポインタがあります。ポインタは,メモリー・アドレスを格納するための特殊な変数です。ポインタを使うと,任意のメモリー領域を読み書きできて便利なのですが,誤って不適切なメモリー領域に書き込みを行うと,プログラムがクラッシュしてしまう恐れがあります。

 C言語やC++のプログラマがつい犯してしまうミスとして有名なものに,メモリー・リーク(memory leak=メモリの漏れ)があります。メモリー・リークとは,プログラムの実行時に動的に確保されたメモリー領域が,プログラムの終了時に解放されず,確保されたまま残ることです。メモリー・リークが積もり積もると,メモリー容量が不足してコンピュータがダウンしてしまいます。メモリー・リークが発生するのは,プログラマがメモリー領域を解放する処理の記述をうっかり忘れたことが原因です。

●Javaによる改善

 Javaでは,C言語やC++の良いところだけを引継ぎ,プログラムを誤動作させる問題点を取り除いています。さらに,GUI,マルチ・スレッド,およびネットワークなど,時代に見合った機能を標準で提供しています。文法が似ているので,C言語やC++のプログラミング経験があれば,容易にJavaをマスターできるのも魅力です。Javaで記述されたプログラムは,次回から説明します。ここでは,C言語やC++の問題点をJavaがどう改善しているかを説明しましょう。

 Javaでは,プログラムをクラスの集合体として記述しなければならないようになっています。これによって,Javaを使う限り強制的にオブジェクト指向プログラミングをさせられることになります。プログラムを整理することが不可欠になるのです。Javaを使えば,完全なオブジェクト指向プログラミングが実現できます。

 Javaでは,ポインタが廃止されています。従って,不適切なメモリー領域をアクセスすることは原理的に不可能です。これは,Javaアプレットの安全性を高める効果もあります。もしも,WebサーバーからダウンロードしたJavaアプレットが,コンピュータの任意のメモリー領域をアクセスできるとしたら,あまりにも危険でしょう。

 Javaでは,プログラムの実行時に動的に確保されたメモリー領域が,自動的に解放されるようになっています。従って,メモリー・リークは発生しません。C言語やC++のプログラマなら,この機能だけでもJavaに飛びつきたくなるくらいです。Java仮想マシンがガベージ・コレクタというプログラムを持っていて,メモリーが足りなくなると,どこからも使用されていないメモリー領域を解放してくれます。この機能をガベージ・コレクションと呼びます。ガベージ・コレクタ(garbage collector)とは「ゴミ屋」という意味で,ガベージ・コレクション(garbage collection)とは,「ゴミ集め」という意味です。使われていないメモリー領域がゴミだというわけです。

●おわりに

 Javaの学習を始めたいと思っている人から「Javaの前にC言語とC++をマスターしておいた方がいいでしょうか?」という質問を受けることがよくあります。筆者は,「時間があるなら,C言語とC++を先に学習してください。時間が無いなら,いきなりJavaの学習からスタートしてもOKです」と答えるようにしています。もともとポインタやメモリー・リークなど無いものであり,プログラムはクラスの集合体として作成しなければならないことが当たり前だと考えても,何ら問題ないからです。ただし,Javaの学習を進めていくうちに,ポインタに似た概念が登場することがあります。プログラマのたしなみとして,単独の関数や変数をイメージする能力も必要でしょう。皆さんには,C言語とC++の概要だけでもマスターしておくことをお奨めします。