文字を表示する


はじめての D 言語プログラミング

D 言語は、基本的に C 言語と強く関連していて、C 言語を基本としている手続き型に近いオブジェクト指向型言語です。 ただし、C++ 言語とは違って互換性は保障されていません。 配列やポインタの扱いなどで異なる部分が多くありますし、構造体などの宣言文も互換性はありません。

細かい説明は後述するので、この場ではとりあえず文字を表示する方法を試してみましょう。 文字を表示できなければ、プログラムが正常に動作しているのかどうかも確認することができません。

D 言語は C 言語と同様に、言語レベルでシステムを参照するような機能は提供されていません。 文字列をコマンドラインに表示するには、言語からシステムのサービスを呼び出す必要があるのです。 C 言語に文字を表示するという命令自体は存在せず、printf() という標準関数を使ってシステムのサービスにアクセスして文字列を表示していたのと考え方は同じです。

C 言語では、printf() 関数などを使って入出力を行うために #include プリプロセッサ命令を使っていました。 しかし D 言語にはプリプロセッサというものは存在しません。 D 言語では、ヘッダファイルではなく、モジュールという単位で機能が提供され、モジュールの利用者はモジュールをソースコードから参照して機能にアクセスします。 Java や C++ の経験者には、名前空間やパッケージという表現がおなじみかもしれません。

C 言語では #include でテキストとしてコードを挿入していましたが、D 言語では import 宣言を用いてモジュールをロードします。 モジュールは単純なファイルパスでアクセスするのではなく、モジュールであることを宣言したときに指定されたモジュール名に基づきます。 モジュール名は階層化が可能で、ファイルパスを指定するときのディレクトリ階層に酷似しています。 このとき、目的のモジュールまでの各階層をパッケージと読んでいます。

import モジュール名 , モジュール名 , ... ;

モジュールについて、詳しくは基本を網羅してから解説しますが、入出力などの便利な機能にアクセスするには、とにかくモジュールをロードしなければならないと考えてください。 例えば、kitty . rena という名前のモジュールが存在する場合、モジュール rena は kitty パッケージに属していると表現します。 中核となるモジュール群はすべて std パッケージ以下に配置されています。 最もよく使うであろう、入出力に関するモジュールは std . stream モジュールです。 私たちは、まずこのモジュールをロードする必要があります。

import std . stream;

これで、文字を画面に表示する準備は整いました。 C 言語の拡張子は、*.c でしたが、D 言語の拡張子は誰もが予想できる *.d です。 関数という概念は失われておらず、D 言語のアプリケーション・エントリーポイントは main() 関数であると定められています。

int main() { ... }

プログラムを実行すると main() 関数が呼び出され、main() 関数を終了するとアプリケーションは終了します。 main() 関数はシステムに数値を返します。 関数の引数や戻り値という概念も C 言語とまったく同じなので、return 分を使って数値をシステムに返します。

return 戻り値 ;

つまり、必要最小限の D 言語プログラミングは次のようなものになるでしょう。 適当な名前のテキストファイルを用意し *.d という拡張子でコードを保存してコンパイルしてみてください。

int main() {
 	return 0;
}

コンパイルするには dmd コマンドに続けてコンパイルするソースファイルを指定します。 このプログラムは、実行しても何も処理を行わずに即座に制御を返す最も単純な D 言語プログラムです。 D 言語は C 言語や Java 言語などと同様に、トークンを適切に認識であれば、その間に半角のスペース文字やタブ文字、改行を自由に挿入することができます。 例えば、次のようなプログラムを問題はありません。

int
	main() {return
0;	}

このソースコードは空白や改行、タブ文字などが適切なレイアウトで挿入されていないため、人間にとっては極めて読みづらいソースコードですが、個々の命令は適切なものなのでコンパイラにとっては適切に処理することができるのです。

逆に、次のコードはコンパイルすることができません。

int ma in() {
	return0;
}

なぜならば、main( )関数の ma と in の間に空白文字が挿入されているため、コンパイラはこれらを個別の処理単位として扱おうとします。 しかし、ma というコードと in() という名前の関数を適切に処理することができないので、エラーとなってしまいます。 また、return キーワードと 0 の間に空白が存在しないため、コンパイラは return0 という単位で扱おうとしてしまいます。 return0 という名前の命令は存在しないため、これもエラーとなります。

文字をコマンドラインに表示する方法は、std . stream モジュールが公開している stdout というオブジェクトを利用します。 クラスやオブジェクトについては後ほど詳しく解説します。 stdout は標準出力を参照しているストリームで、write() または writeLine() 関数を使って文字列を送信することができます。

stdout.writeLine("出力する文字列");

stdout は標準出力を参照しているので、stdout に文字列を送信すると、システムの標準出力に文字が表示されるでしょう。 つまり、上記の文の「出力する文字列」を好きな文字に変更すれば、それが表示されるということです。 D 言語では、C 言語同様に文字列リテラルを二重引用符 " で囲まなければなりません。

write() 関数は文字列以外にも、数値など様々な値を文字として表示することができます。 一方で、writeLine() 関数は文字列だけしか受け取ることができません。 writeLine() 関数で文字列を表示した場合、自動的に文字列の末尾にシステム固有の改行文字が追加されます。

import std.stream;

int main() {
	stdout.writeLine("Kitty on your lap");
	return 0;
}

このプログラムを実行すると、標準出力に "Kitty on your lap" という文字列が表示されるでしょう。 C++ や Java の経験者には、stdout は、標準ランタイムで提供されている入出力用の stream 抽象クラスの実装であるといえば理解できるでしょう。 C 言語プログラマは、stdout が FILE 構造体のようなものだと考えてください。

因みに、D 言語の標準ライブラリは C 言語プログラマに配慮して C 言語の関数に互換性のある関数郡を提供しています。 C 互換の関数を利用するには std . c パッケージから目的のモジュールを読み込む必要があります。 例えば、C 言語の標準ライブラリ stdio.h に対応しているのは std . c . stdio モジュールとなります。

import std.c.stdio;

int main() {
	printf("Kitty on your lap\n");
	return 0;
}

import 宣言以外はどう見ても C 言語とそっくりであることが確認できます。 C 言語を習得しているプログラマであれば、基本的な言語仕様は共通しているのでスムーズに習得できるはずです。



前のページへ戻る次のページへ