「D言語」の版間の差分

出典: フリー教科書『ウィキブックス(Wikibooks)』
削除された内容 追加された内容
デバッグ用コメントが混入してたので除去。
182 行 182 行


int some;
int some;
readf("%d",&some); // 8
readf("%d",&some);


writef("you input %d\n",some );
writef("you input %d\n",some );

2020年6月21日 (日) 09:25時点における版

Wikipedia
Wikipedia
ウィキペディアD言語の記事があります。

情報技術 > プログラミング > D言語


D言語はWalter Bright氏によって開発が始められた言語です。

2010年代にFacebook社がD言語を支援したので有名になりましたが、しかしFaqcebook開発ではなくWalter Bridge氏の開発する言語あり、2001年からD言語は公開されています。

なお、Walter Bright氏は、低価格/高速コンパイラで名を馳せた Datalight C。世界初のnative-C++コンパイラ Zortech C++、そしてその後継であるSymentec C++、Java開発環境 Cafeなどで知られています

公式名称は「D language」(D言語)または「D programming language」ですが、英語ではネット検索などの利便性のため「dlang」と表記される場合もあります。


目次

このページ「D言語」は、まだ書きかけです。加筆・訂正など、協力いただける皆様の編集を心からお待ちしております。また、ご意見などがありましたら、お気軽にトークページへどうぞ。

D言語の特徴

D言語は、C言語とのソース互換性を持ってないです。(一方、C++は標準C言語とのソース互換性を持っている。)

D言語の開発者たちは、標準C言語とのソース互換性を持たせると、古い時代遅れのノウハウ(バッドノウハウ)を引きずりかねない、と考えているので、あえてD言語にはC言語とのソース互換性を持たせないでいます。

また、D言語はシステムプログラミング言語を目指しています。システムプログラミング言語とは、オペレーティングシステムそのものの開発もできる言語です。(たとえばC言語はシステムプログラミング言語です。LinuxはC言語で書かれています。)

実際にD言語で開発されたOSが市販や公開されているかはともかく、D言語がOS開発言語も目指してていることは、利用上、とても重要です。なぜなら、ユーザーにとって手間が掛かるかもしれないが、とりあえず、今までC言語で出来たハードウェア制御や、D言語でもひととおり出来るようになる予定・目標だからです。


D言語の特徴をいくつか上げておきましょう。

  • ネイティブコンパイルされるため動作が速い - インタプリタや仮想機械上で動作する言語に比べて非常に高速です。
  • 自動メモリ管理 - ガベージコレクタ(GC)を搭載しているため、メモリの取得・開放に関してプログラマが気にする必要はありません。もちろん手動でメモリを管理する方法も用意されています。

コンパイラを動かしてみよう

まずは環境がちゃんと動くか試してみましょう。例として、"Hello World"という文字列を表示させるプログラムを作ってみることにします。テキストファイルを新しく作り、hello.dという名前にしたらテキストエディタで以下のように編集します。

コード例
import std.stdio;

void main(){
    writeln("Hello World!");
}

さぁ、これを動かしてみましょう。

rdmd hello.d

動きましたか? 動かなかったのなら、環境変数などをもう一度、確認してみてください。

文法の解説

読者のほとんどはC言語の文法を知っているかもしれませんが、おおまかに上記コードで使用されている文法を説明すると

import モジュール名

でモジュールを導入します。D言語の impoert は、C言語でいう #include 文に相当します。


main() というのは、D言語に必ず1つだけ存在する「関数」(かんすう)であり、ここから開始します(なお、どのプログラム言語でも、プログラムの開始点のことを「エントリポイント」といいます)。つまり、D言語のエントリポイントは「main()」関数です。

プログラム言語において「関数」とは、処理をまとめたモノです。


writeln というのは、D言語においてコマンド画面などに文字表示をする組み込み関数です。writeln は文末を自動的に改行します。(なお、C言語に writeln は無いです。C言語で文字表示する関数は別の関数ですが、本書はC言語の教科書ではないので、これ以上のC言語の文字表示についての説明は省略します。)


D言語にかぎらずC言語などでも、文字表示など基本的な機能のいくつかは、プログラム言語によって最初から用意されており、使用の際には、コード中に使用したい箇所でその関数の名前を書くことで呼び出せます。

また、関数や組み込み関数になにかの値を入力させる場合、D言語にかぎらずC言語などでも、関数名のあとに丸カッコ()がつき、さらにその丸カッコ内にその入力値などの情報が書かれます。

画面に表示する文字列を扱いたい場合、二重引用符 " " でくくります。


Windows版 D言語では現状、日本語の表示があまりよくないです。文字コードは UTF-8 にしないとエラーになります。 ですが、UTF-8にしてもWindows版D言語では文字バケをします。

なので、LinuxでD言語を使いましょう。

なお、Linuxなどで一般的に使われている文字コードが UTF-8です。つまり D言語は文字コードを Linux に合わせていることになります。なお、Windowsの開発元のマイクロソフト社も、Wondows10で将来的に文字コードをUTF-8に移行し対応する公式声明を出しています。

D言語の文法について

もし読者が英語が得意でプログラムについて一通り分かっているなら、詳細については公式のドキュメントを読んだ方が早いと思います。本wikiでは初心者向けに書いていきます。

初心者の方は、日本語訳もされている D言語ツアーを読むと良いかもしれません。D言語ツアーは初心者むけの公式ガイドの和訳です。


概観

D言語の構文はC言語に似ており、テキストに書かれたプログラムを1行ずつ処理していく手続き型言語です。基本的な流れや、一つ一つの文、コメント、演算子などもC言語を元にしています。詳しくはC言語の該当項目を参照してください。(リンク: wikibooks『C言語』)

ただしC言語と異なる部分もあるため、C言語を参考にするには注意が必要です。#include <stdio.h>の代わりにimport std.stdio;となる事や、printf("文字列")の代わりにwrite("文字列")を使う事は知らなければなりません。

型(かた)というのは変数の形式です。

コンピューターでは数値として整数(-1,0,1,2等)や実数(1.4142,3.1415 など)を扱う事ができます。 C言語と同様に、D言語ではこれらをint型、float型と言います。 他に重要な型として、文字1文字を表す文字型があります。 これもC言語と同様に、char型として存在します。

ポインタ型という型もあり、そのポインタ型であるT* aはT型へのポインタを表します。

配列型という型もあり、その配列型であるT[] aはT型の配列を表します。

char[] mojiretu は char型の配列、つまりchar型の変数の いくつかが一まとまりになったもの、となります。

文字型は1文字を扱う事よりも、文字の集まった文字列を扱う事が多いので、string型という元々配列の型が用意されています。これは(1.Xでは)char[]と同じものです。

クラス / 構造体 / union / enum という型もあります。これらは別の場所で宣言する必要があり、その時に指 定した一意文字列を型に指定します。

型の異なった変数を一まとめにして扱う事ができます。

関数型/delegate型はTODO。

また void という特殊な型があります。これは値が無いことを表します。


基本テクニック

書式つき文字出力

文末に改行を追加して文字列を出力をしたい場合、 writeln です。

D言語に限らず、他の多くの言語でも、〇〇ln の命令はたいてい、文末に改行を追加します。


writef だと、下記のように、変数の表示位置を指定できます。

import std.stdio;

void main(){

   int kazu = 3 + 5;

   writef("kazu is %d",kazu);
}


実行結果
kazu is 8

十進数(decimal)で表示したい場合は、その位置に %d を入れます。

キーボードから数値入力したい場合

文字の出力ではなく、キーボードから文字列の入力をさせたい場合、D言語では readln() 関数という組み込み関数で可能です。


import std.stdio;

void main(){
    writeln("please input something");
    string str1 = readln();

    writef("you input %s", str1);

}


実行結果の例
please input something
fff
you input fff


readf() を使うと、型を指定して入力できます。

import std.stdio;

void main(){      
    writeln("Please input number");

    int some;
    readf("%d",&some); 

    writef("you input %d\n",some );
}


実行結果の例
Please input number
4
you input 4



これだと、

各論

宣言

変数のデータを扱う時、それぞれに名前が無いと見分けがつかなくて困ります。そのために名前を付ける作業です。

変数

変数とは一時的に値を代入する事ができるものです。

int i;
float a = 10.05;
初期化子

初期化子では式とは違った構文になっているので注意してください。

構造体

いくつかの値のペア。定義があればその名前を型として変数として宣言できます。

struct S
{
    int i;
    string str;
}
S s1;


標準C言語の構造体はメンバ関数を持てないですが、しかしD言語ではメンバ関数をもてます。

なおC++でもメンバ関数をもてます。

クラス

クラスとは、大まかには構造体を便利にした物。構造体と違って参照型の変数として扱われる。

class C
{
    int i;
    string str;
}
C c1;

なお、標準C言語にクラスの機能は無い。C++やC#にはクラスがある。


共用体

union 型のことを共用体とも言う。 メモリを共有するための型。

標準C言語にも共用体や列挙体がある。(列挙体については後述)

列挙体

enum型のことを列挙体ともいう。

値の列挙をするための方。

enum COLOR
{
    WHITE, BLACK, RED, YELLOW, GREEN, BLUE
}
COLOR color;

注意点として、D言語の列挙体は、CやC++とは少し違います。

演算

演算順位が高い方が先に計算されます。 なお演算順位は以下のようになっています。

TODO

条件文

条件文は値によって実行する処理を分ける時に使います。

if(x % 2 == 0)
{
    writeln("x is even number");
}
else
{
    writeln("x is odd number");
}
C言語を参照: C言語/制御文

繰り返し文

繰り返し文は値によって処理を繰り返す時に使います。

for(int i=0; i<100; i++)
{
    writeln( "i = ", i );
}
C言語を参照: C言語/制御文#繰り返し文

クラス

クラスは複数の変数を一まとめにし、それらを扱う関数も内包することで、簡潔で他のプログラムに依存しない独立した処理を可能とします。また、クラスは雛形(ひながた)であり、同じ性質を持ったデータ(オブジェクト)を多数作る事ができます。

実体化

クラスは雛形に過ぎないため、実際に変数として使うためには定義、宣言した後に実体化(インスタンス化)という作業が必要になります。Cというクラスのオブジェクトc1は

C c1;    // 宣言
c1 = new C();

で実体化できます。これ以降c1をC型の変数として扱う事ができます。newが実体化する命令で、その対象はCというクラス、という事です。空白の()は後述するコンストラクタに何も指定しない事を意味します。

メンバ変数

classの中に定義された変数の事を特にメンバ変数と言います。 オブジェクトの持つデータそのもので、これを扱いやすくするための仕組みが以下になります。

メンバ関数

classの中に定義された関数を特にメンバ関数と言います。 メンバ変数に対する決まりきった処理を他のオブジェクトに依存すると、関わるオブジェクト数が増えるため複雑で読みにくく直しにくいコードになります。メンバ変数の事はメンバ関数に任せましょう。

コンストラクタ

this()という名前を持つ特殊なメンバ関数です。クラスをオブジェクトとして実体化する際に、this関数の中で定義された初期化処理を実行します。引数なしの場合はメンバ変数のデフォルト値を与えるのに使います。初期化するだけなので、返り値はありません。

this()
{
    i = 0;
    str = "Default string";
}

引数ありの場合も定義でき、何個でも定義できます(オーバーライド)

this(int x)
{
    i = x;
    str = "int override";
}
this(string strin)
{
    i = 0;
    str = strin.idup;
}

ここで定義した関数は、new実行時にC(引数)と表記する事で、引数に応じてthis(引数)関数を実行します。様々な初期状態を持った同じクラスのオブジェクトを作るのに便利です。

演算子オーバーロード

四則演算(+-*/)など多くの演算記号を、クラスに対してまるごと作用させる演算を定義できます。

契約・単体テスト