(Translated by https://www.hiragana.jp/)
Ada - Wikibooks コンテンツにスキップ

Ada

出典しゅってん: フリー教科書きょうかしょ『ウィキブックス(Wikibooks)』
Wikipedia
Wikipedia
ウィキペディアAda記事きじがあります。

このAdaチュートリアルは、Adaプログラミング言語げんご興味きょうみっているひと、またはすでにAdaをっているがよりふか理解りかいしたいとおもっているひとけに作成さくせいされています。 Adaは、高信頼こうしんらいせいもとめられるシステム開発かいはつ組込くみこみシステム開発かいはつてきした言語げんごであり、現在げんざいでもおおくの産業さんぎょう分野ぶんや使つかわれています。

このチュートリアルでは、Ada言語げんご基本きほんてき概念がいねんからはじめ、プログラミングの基礎きそ解説かいせつしています。初心者しょしんしゃでも理解りかいしやすいように、具体ぐたいてきれいまじえながら、丁寧ていねい説明せつめいしていきます。

このチュートリアルをつうじて、Adaをよりふか理解りかいし、高信頼こうしんらいせいたかいソフトウェア開発かいはつ役立やくだてていただければさいわいです。

Adaの概要がいよう

[編集へんしゅう]

[Adaがどのようなプログラミング言語げんごであるか、開発かいはつ背景はいけい利点りてんについて説明せつめいします。]

Adaは、1980年代ねんだいアメリカ合衆国あめりかがっしゅうこく国防総省こくぼうそうしょう開発かいはつした高信頼こうしんらいせいソフトウェアを開発かいはつするためのプログラミング言語げんごです。その民間みんかん分野ぶんやでも利用りようされるようになり、現在げんざいでも航空こうくう宇宙うちゅう鉄道てつどう医療いりょう機器ききなど、たか信頼しんらいせいもとめられる分野ぶんやひろ使つかわれています。

Adaの特徴とくちょうとしては、以下いかのようなてんげられます。

  • つよ型付かたつけ:変数へんすう関数かんすうなどのデータがた厳密げんみつ定義ていぎされ、コンパイルかたエラーを検出けんしゅつできるため、バグの発生はっせい防止ぼうしできます。
  • 相互そうご排除はいじょ機能きのう:タスクあいだ相互そうご排除はいじょ機能きのう強力きょうりょくで、デッドロックやライブロックなどの問題もんだいすくなく、安全あんぜん並行へいこう処理しょり実現じつげんできます。
  • メモリ管理かんり:Adaにはガベージコレクション機能きのうがあるため、メモリリークやじゅう解放かいほうのような問題もんだいこりにくく、安全あんぜんなメモリ管理かんり可能かのうです。
  • だい規模きぼなプログラムの開発かいはつてきした機能きのう:Adaには、パッケージ、抽象ちゅうしょうがた、ジェネリック、タスクなど、だい規模きぼなプログラムの開発かいはつ必要ひつよう機能きのう豊富ほうふにあります。
  • ドキュメント生成せいせい:Adaには、コードから自動的じどうてき文書ぶんしょ生成せいせいする機能きのうがあり、ソフトウェア開発かいはつにおける文書ぶんしょ作成さくせい手間てまはぶくことができます。

Adaの利点りてんとしては、高信頼こうしんらいせい安全あんぜんせい保守ほしゅせい品質ひんしつたかさなどがげられます。ただし、Adaの学習がくしゅう曲線きょくせんがややたかく、一般いっぱんてき言語げんごくらべると、使つかいこなすのに時間じかんがかかることがあります。

環境かんきょう設定せってい

[編集へんしゅう]

[Adaの開発かいはつ必要ひつようなソフトウェアやツールをインストールし、環境かんきょう構築こうちくする方法ほうほうについて説明せつめいします。]

Adaの開発かいはつ環境かんきょう構築こうちくするためには、GNATというコンパイラをインストールする必要ひつようがあります。GNATは、Ada言語げんごのフリーでオープンソースな実装じっそうであり、GNU Compiler Collection (GCC) にふくまれています。

Debian linux へのインストール

[編集へんしゅう]
  1. ターミナルをひらきます。
  2. sudo apt updateコマンドを実行じっこうして、パッケージリストを更新こうしんします。
  3. sudo apt-get install gnatコマンドを実行じっこうして、GNATパッケージをインストールします。
  4. インストールが完了かんりょうしたら、gnat --versionコマンドを実行じっこうして、GNATのバージョンを確認かくにんします。

MSYS2/Windows へのインストール

[編集へんしゅう]

MSYS2にGNATをインストールする手順てじゅん以下いかとおりです。

  1. MSYS2をインストールします。公式こうしきサイトからダウンロードして、指示しじしたがってインストールしてください。
  2. MSYS2をひらきます。ひらいたコンソールで以下いかのコマンドを実行じっこうして、パッケージリストを更新こうしんします。
    pacman -Syu
    
  3. GNATをインストールするために、以下いかのコマンドを実行じっこうして必要ひつようなパッケージをインストールします。 このコマンドは、GNATのパッケージにふくまれているmingw-w64-x86_64-gcc-adaパッケージをインストールします。
    pacman -S mingw-w64-x86_64-gcc-ada
    
  4. インストールが完了かんりょうしたら、gnat --versionコマンドを実行じっこうして、GNATのバージョンを確認かくにんします。

macOS へのインストール

[編集へんしゅう]

macOSにGNATをインストールする手順てじゅん以下いかとおりです。

  1. Homebrewをインストールします。ターミナルをひらいて、以下いかのコマンドを実行じっこうします。
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
    
  2. GNATをインストールするために、以下いかのコマンドを実行じっこうします。 このコマンドは、GNATのパッケージをHomebrewからインストールします。
    brew install gnat
    
  3. インストールが完了かんりょうしたら、gnat --versionコマンドを実行じっこうして、GNATのバージョンを確認かくにんします。

FreeBSD へのインストール

[編集へんしゅう]

FreeBSDにGNATをインストールする手順てじゅん以下いかとおりです。

  1. pkgを更新こうしんします。ターミナルをひらいて、以下いかのコマンドを実行じっこうします。
    % sudo pkg update
    
  2. GNATをインストールするために、以下いかのコマンドを実行じっこうします。 このコマンドは、GNATのパッケージにふくまれているgcc-adaパッケージをインストールします。
    % sudo pkg install gcc-ada
    
  3. インストールが完了かんりょうしたら、gnat --versionコマンドを実行じっこうして、GNATのバージョンを確認かくにんします。
GNATについて
GNATは、GNU Ada Compilerとしてられており、GNUプロジェクトの一部いちぶであるため、一般いっぱんてきにはGNU Adaとばれています。GNATの名称めいしょうは、GNU Ada Translatorの略称りゃくしょうであり、最初さいしょのリリースが1987ねんおこなわれたさいには、AdaのコンパイラとしてははじめてGNUプロジェクトにふくまれていたことから、GNATと名付なづけられました。その、GNATはGNUプロジェクトの一部いちぶとして、オープンソースのAdaコンパイラとして発展はってんしてきました。 ただし、GNATの商用しょうようばんであるGNAT Proは、GNU Adaではなく、AdaCoreしゃ独自どくじ開発かいはつした製品せいひんとして販売はんばいされています。GNAT Proは、GNAT GPLにくらべて商用しょうよう利用りようてきした機能きのうやサポートが提供ていきょうされています。また、GNAT Proの利益りえき一部いちぶは、GNUプロジェクトに寄付きふされています。

トップレベルのプログラム構造こうぞう

[編集へんしゅう]

Adaプログラムのトップレベルの構造こうぞうは、以下いかのようになります。

with パッケージめい;
use パッケージめい;

プログラムめい is

    -- 定数ていすうかた変数へんすう、サブプログラム、タスクなどの宣言せんげん

begin

    -- プログラムの実行じっこう部分ぶぶん

end プログラムめい;


withぶんは、使用しようするパッケージを指定していするために使用しようされます。useぶんは、パッケージの使用しよう方法ほうほう指定していします。

プログラムめいは、プログラムの名前なまえ指定していします。プログラムめいしたに、定数ていすうかた変数へんすう、サブプログラム、タスクなどを宣言せんげんすることができます。

beginキーワードののちには、プログラムの実行じっこう部分ぶぶんつづきます。

ソースコードのファイルめいのルールは、以下いかのようになります。

  • ファイルめいは、プログラムめいおなじにする必要ひつようがあります。
  • Adaのソースファイルは、.adb本体ほんたい)と.ads仕様しよう)の2つの拡張子かくちょうしつことができます。
  • .adbファイルと.adsファイルのペアは、おな名前なまえ必要ひつようがあります。
  • ただし、プログラムがひとつの.adbファイルで完結かんけつしている場合ばあい.adsファイルは不要ふようです。

たとえば、以下いかのようなファイル構成こうせいになります。

my_program.adb  -- プログラムの本体ほんたい
my_program.ads  -- プログラムの仕様しよう

コメント

[編集へんしゅう]

Adaのコメントは、ダブルハイフン(--)ではじまり、どのくだりにも表示ひょうじすることができます。コメントはコンパイラによって無視むしされ、コードを記録きろくするために使用しようされます。

以下いかは、Adaのコメントのれいです:

-- これはコメントです。

コメントは、コードの一部いちぶ目的もくてき説明せつめいしたり、追加ついか情報じょうほう提供ていきょうしたり、現在げんざい使用しようされていないコードのセクションをマークするために使用しようすることができます。

コメントは、コードをよりみやすく、理解りかいしやすくするための貴重きちょうなツールです。また、コードの保守ほしゅせい向上こうじょうさせ、デバッグを容易よういにする効果こうかもあります。


データがた変数へんすう

[編集へんしゅう]

Adaには、さまざまなデータがたがあります。このしょうでは、Adaで使用しようできる主要しゅようなデータがた変数へんすう宣言せんげん方法ほうほう、データの代入だいにゅう演算えんざんについて説明せつめいします。

データがた

[編集へんしゅう]

Adaには、以下いかのような主要しゅようなデータがたがあります。

  • 整数せいすうがた(Integer)
  • 実数じっすうがた(Float)
  • 文字もじがた(Character)
  • 真偽しんぎがた(Boolean)
  • 列挙れっきょがた(Enumeration)
  • 配列はいれつがた(Array)
  • レコードがた(Record)
  • 構造こうぞう体型たいけい(Access)

これらのデータがたわせて、より複雑ふくざつなデータがた定義ていぎすることもできます。

整数せいすうがた(Integer)

[編集へんしゅう]

整数せいすうがた(Integer)は、Adaでもっと一般いっぱんてきなデータがたひとつであり、符号ふごう整数せいすうあらわします。Integerの範囲はんい実装じっそうによってことなりますが、通常つうじょうは-2^31から2^31-1までのあらわすことができます。以下いかは、Integerがた使用しようしたコードれいです。

integer_example.adb
with Ada.Text_IO;         use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

procedure Integer_Example is
   age : Integer := 25;
begin
   Put("I am ");
   Put(age, 2);
   Put(" years old.");
end Integer_Example;

実数じっすうがた(Float)

[編集へんしゅう]

実数じっすうがた(Float)は、浮動ふどう小数点しょうすうてん数値すうちあらわすために使用しようされます。Adaには、いくつかのことなる精度せいどのFloatがたがあります。たとえば、Floatがた通常つうじょう単精度たんせいど浮動ふどう小数点しょうすうてんすうあらわし、Long_Floatがた倍精度ばいせいど浮動ふどう小数点しょうすうてんすうあらわします。以下いかは、Floatがた使用しようしたコードれいです。

float_example.adb
with Ada.Text_IO;       use Ada.Text_IO;
with Ada.Float_Text_IO; use Ada.Float_Text_IO;

procedure Float_Example is
   pi : Float := 3.14159;
begin
   Put("The value of Pi is ");
   Put(pi, 1, 5);
end Float_Example;

文字もじがた(Character)

[編集へんしゅう]

文字もじがた(Character)は、単一たんいつ文字もじあらわします。Adaの文字もじがたは、Unicode文字もじセットをサポートしています。以下いかは、Characterがた使用しようしたコードれいです。

character_example.adb
with Ada.Text_IO; use Ada.Text_IO;

procedure Character_Example is
   letter : Character := 'A';
begin
   Put("The first letter of the alphabet is ");
   Put(letter);
end Character_Example;

真偽しんぎがた(Boolean)

[編集へんしゅう]

真偽しんぎがた(Boolean)は、しんまたはにせ論理ろんりあらわします。以下いかは、Booleanがた使用しようしたコードれいです。

boolean_example.adb
with Ada.Text_IO; use Ada.Text_IO;

procedure Boolean_Example is
   is_raining : Boolean := True;
begin
   if is_raining then
      Put("Bring an umbrella.");
   else
      Put("Leave your umbrella at home.");
   end if;
end Boolean_Example;

列挙れっきょがた(Enumeration)

[編集へんしゅう]

列挙れっきょがた(Enumeration)は、指定していされた集合しゅうごうあらわします。たとえば、以下いかのコードれいでは、曜日ようびあらわすために、列挙れっきょがた使用しようしています。

enumeration_example.adb
with Ada.Text_IO; use Ada.Text_IO;

procedure Enumeration_Example is
   type Day is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);
   today : Day := Tuesday;
begin
   Put("Today is ");
   case today is
      when Monday =>
         Put("Monday");
      when Tuesday =>
         Put("Tuesday");
      when Wednesday =>
         Put("Wednesday");
      when Thursday =>
         Put("Thursday");
      when Friday =>
         Put("Friday");
      when Saturday =>
         Put("Saturday");
      when Sunday =>
         Put("Sunday");
   end case;
end Enumeration_Example;

配列はいれつがた(Array)

[編集へんしゅう]

配列はいれつがた(Array)は、おなじデータがた集合しゅうごうあらわします。配列はいれつは、固定こていサイズまたは可変かへんサイズの場合ばあいがあります。以下いかは、Integerがた配列はいれつ使用しようしたコードれいです。

erray_example.adb
with Ada.Text_IO; use Ada.Text_IO;

procedure Array_Example is
   -- 配列はいれつ宣言せんげんする
   type My_Array is array(1..5) of Integer;
   A : My_Array := (1, 2, 3, 4, 5);
begin
   -- 配列はいれつ要素ようそにアクセスする
   Put_Line("A(1) = " & Integer'Image(A(1)));
   Put_Line("A(2) = " & Integer'Image(A(2)));

   -- 配列はいれつ要素ようそ変更へんこうする
   A(1) := 10;
   A(2) := 20;

   -- 変更へんこうされた要素ようそ出力しゅつりょくする
   Put_Line("A(1) = " & Integer'Image(A(1)));
   Put_Line("A(2) = " & Integer'Image(A(2)));

   -- 配列はいれつぜん要素ようそにアクセスする
   for I in A'range loop
      Put_Line("A(" & Integer'Image(I) & ") = " & Integer'Image(A(I)));
   end loop;
end Array_Example;

レコードがた(Record)

[編集へんしゅう]

レコードがた(Record)は、ことなるデータがた集合しゅうごうあらわします。レコードには、名前なまえきフィールドがあります。以下いかは、Personという名前なまえのレコードがた使用しようしたコードれいです。

record_example.adb
with Ada.Text_IO; use Ada.Text_IO;

procedure Record_Example is
   type Person is record
      Name : String(1..20);
      Age : Integer;
      Is_Married : Boolean;
   end record;

   p : Person := ("John", 30, False);
begin
   Put("Name: ");
   Put(p.Name);
   New_Line;
   Put("Age: ");
   Put(p.Age, 2);
   New_Line;
   Put("Married: ");
   if p.Is_Married then
      Put("Yes");
   else
      Put("No");
   end if;
end Record_Example;

構造こうぞう体型たいけい(Access)

[編集へんしゅう]

構造こうぞう体型たいけい(Access)は、動的どうてき確保かくほされたデータ構造こうぞうあらわします。構造こうぞうたいには、名前なまえきフィールドがあります。以下いかは、Personという名前なまえのAccessがた使用しようしたコードれいです。

with Ada.Text_IO; use Ada.Text_IO;

procedure Access_Example is
   type Person is record
      Name : String(1..20);
      Age : Integer;
      Is_Married : Boolean;
   end record;

   type Person_Ptr is access Person;

   p : Person_Ptr :== new Person'(Name ==> "John", Age ==> 30, Is_Married ==> False);
begin
   Put("Name: ");
   Put(p.Name);
   New_Line;
   Put("Age: ");
   Put(p.Age, 2);
   New_Line;
   Put("Married: ");
   if p.Is_Married then
      Put("Yes");
   else
      Put("No");
   end if;
end Access_Example;

変数へんすう宣言せんげん

[編集へんしゅう]

変数へんすう宣言せんげんするには、以下いかのような構文こうぶん使用しようします。

variable_name : data_type := initial_value;

変数へんすうめいは、英数字えいすうじとアンダースコアから構成こうせいされます。データがたは、前述ぜんじゅつのデータがたのいずれかを指定していします。初期しょきはオプションで、変数へんすう宣言せんげん代入だいにゅうされます。

たとえば、整数せいすうがた変数へんすうx宣言せんげんし、初期しょき10設定せっていする場合ばあいは、以下いかのようになります。

x : Integer := 10;

データの代入だいにゅう

[編集へんしゅう]

変数へんすうにデータを代入だいにゅうするには、以下いかのような構文こうぶん使用しようします。

variable_name := new_value;

変数へんすうめいは、代入だいにゅうさき変数へんすう指定していします。あたらしいは、代入だいにゅう演算えんざん:=のちつづけて指定していします。

たとえば、上記じょうきれい宣言せんげんした整数せいすうがた変数へんすうxに、あたらしい20代入だいにゅうする場合ばあいは、以下いかのようになります。

x := 20;

しき演算えんざん

[編集へんしゅう]

Ada言語げんごでは、しきとは変数へんすう定数ていすう、リテラル関数かんすう、および演算えんざんふくむコードの断片だんぺんです。しきは、しき自体じたいかえすように評価ひょうかされ、変数へんすう取得しゅとくしたり、関数かんすうしたりすることができます。

たとえば、以下いかのコードは、しき使用しようして変数へんすうxとyの加算かさんし、結果けっか変数へんすうzに格納かくのうします。

with Ada.Text_IO; use Ada.Text_IO;

procedure Main is
   x, y, z : Integer;
begin
   x := 10;
   y := 20;
   
   z := x + y;
   
   Put_Line(z'Image);
end Main;

演算えんざん

[編集へんしゅう]

演算えんざんとは、算術さんじゅつ比較ひかく論理ろんり、ビット演算えんざんなど、プログラムで使用しようされる操作そうさあらわ特殊とくしゅ記号きごうです。演算えんざんは、一般いっぱんひとつまたは複数ふくすうのオペランドに適用てきようされます。

Adaには、つぎのような演算えんざん種類しゅるいがあります。

  • 算術さんじゅつ演算えんざん: +、-、*、/、**(べきじょう
  • 比較ひかく演算えんざん: =、/=、<、<=、>、>=
  • 論理ろんり演算えんざん: and、or、not
  • ビット演算えんざん: and、or、xor、not、shl(ひだりシフト)、shr(みぎシフト)

Adaには、C言語げんごのような複雑ふくざつ演算えんざんがないため、明確めいかくでわかりやすいコードがけます。

Adaに特有とくゆう演算えんざんひとつは、範囲はんい演算えんざん(..)です。これは、範囲はんいあらわすために使用しようされます。たとえば、1から10までの整数せいすう範囲はんいあらわすには、1..10ときます。

また、Adaには、剰余じょうよ演算えんざん(mod)があります。これは、2つの整数せいすう剰余じょうよ計算けいさんします。

以下いかは、Adaで算術さんじゅつ演算えんざん使用しようしたれいです。

with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
   X, Y, Z : Integer;
begin
   X := 10;
   Y := 3;
   
   Z := X + Y;
   Put_Line("X + Y = " & Integer'Image(Z));
   
   Z := X - Y;
   Put_Line("X - Y = " & Integer'Image(Z));
   
   Z := X * Y;
   Put_Line("X * Y = " & Integer'Image(Z));
   
   Z := X / Y;
   Put_Line("X / Y = " & Float'Image(Z));
   
   Z := X ** Y;
   Put_Line("X ** Y = " & Integer'Image(Z));
end Main;
出力しゅつりょく
X + Y = 13
X - Y = 7
X * Y = 30
X / Y = 3.333333
X ** Y = 1000

以下いかに、Adaの演算えんざん分類ぶんるいごとに一覧いちらんひょうにまとめました。

算術さんじゅつ演算えんざん
演算えんざん 説明せつめい
+ 加算かさん
- 減算げんざん
* 乗算じょうざん
/ 除算じょざん
mod じょあまり
** べきじょう
比較ひかく演算えんざん
演算えんざん 説明せつめい
= ひとしい
/= ひとしくない
< 未満みまん
<= 以下いか
> よりおおきい
>= 以上いじょう
論理ろんり演算えんざん
演算えんざん 説明せつめい
and 論理ろんりせき
or 論理ろんり
not 否定ひてい
ビット演算えんざん
演算えんざん 説明せつめい
and ビットごとの論理ろんりせき
or ビットごとの論理ろんり
xor ビットごとの排他はいたてき論理ろんり
not ビットごとの否定ひてい
shl ひだりシフト
shr みぎシフト
その演算えんざん
演算えんざん 説明せつめい
& 文字もじれつ連結れんけつ
:= 代入だいにゅう
[] 配列はいれつ要素ようそ参照さんしょう
() 手続てつづきや関数かんすう引数ひきすう指定してい、グループ
. レコードのフィールドの参照さんしょう
.. 範囲はんいあらわ


以上いじょうひょうしめされた演算えんざん適切てきせつ使用しようすることで、Adaプログラムをより効率こうりつてきかつわかりやすく記述きじゅつすることができます。

制御せいぎょ構造こうぞう

[編集へんしゅう]

制御せいぎょ構造こうぞう(Control Structures)は、プログラムのながれを制御せいぎょするための構造こうぞうであり、プログラムをより複雑ふくざつ動作どうさおこなえるようにします。Adaでは、おも条件じょうけん分岐ぶんき(ifぶん)とループ(forぶん)が利用りようされます。

条件じょうけん分岐ぶんき(ifぶん)

[編集へんしゅう]

条件じょうけん分岐ぶんきは、条件じょうけんによって処理しょり分岐ぶんきさせるための構造こうぞうです。ifぶんもちいて、条件じょうけんしんである場合ばあいにせである場合ばあいで、それぞれことなる処理しょりおこなうことができます。

単純たんじゅんなifぶん
if 条件じょうけん then
    しん場合ばあい処理しょり;
end if;
上記じょうき構文こうぶんでは、条件じょうけんしんである場合ばあいしん場合ばあい処理しょり実行じっこうされます。にせである場合ばあいは、なに処理しょりされません。
if-elseぶん
if 条件じょうけん then
    しん場合ばあい処理しょり;
else
    にせ場合ばあい処理しょり;
end if;
上記じょうき構文こうぶんでは、条件じょうけんしんである場合ばあいしん場合ばあい処理しょり実行じっこうされ、にせである場合ばあいにはにせ場合ばあい処理しょり実行じっこうされます。
if-elsif-elseぶん
if 条件じょうけん1 then
    条件じょうけん1がしん場合ばあい処理しょり;
elsif 条件じょうけん2 then
    条件じょうけん2がしん場合ばあい処理しょり;
else
    条件じょうけん1も条件じょうけん2もにせ場合ばあい処理しょり;
end if;
上記じょうき構文こうぶんでは、条件じょうけん1がしん場合ばあいには条件じょうけん1がしん場合ばあい処理しょり実行じっこうされ、条件じょうけん2がしん場合ばあいには条件じょうけん2がしん場合ばあい処理しょり実行じっこうされ、どちらもにせ場合ばあいには、else以下いかにせ場合ばあい処理しょり実行じっこうされます。

caseぶん

[編集へんしゅう]

Adaにおけるcaseぶんは、複数ふくすう条件じょうけん分岐ぶんきおこなうために使用しようされる制御せいぎょ構造こうぞうひとつです。caseぶんは、によってことなるブロックを実行じっこうすることができます。

caseぶん以下いかのような構文こうぶんちます。

case expression is
   when choice1 =>
      -- choice1の処理しょり
   when choice2 =>
      -- choice2の処理しょり
   ...
   when choiceN =>
      -- choiceNの処理しょり
   when others =>
      -- どの条件じょうけんにも一致いっちしない場合ばあい処理しょり
end case;

expressionには条件じょうけん分岐ぶんき対象たいしょうとなるしき指定していします。choiceには条件じょうけん分岐ぶんき候補こうほとなる指定していします。whenキーワードののちつづchoice該当がいとうする場合ばあい、そのブロックない処理しょり実行じっこうされます。最後さいごに、when others使用しようして、どの条件じょうけんにも該当がいとうしない場合ばあい処理しょり指定していすることができます。

反復はんぷく

[編集へんしゅう]

Adaにおけるループ(かえし)は、おな処理しょりかえ実行じっこうするための制御せいぎょ構造こうぞうです。Adaには、以下いかの3つのループがあります。

  • loopループ
  • whileループ
  • forループ

loopループ

[編集へんしゅう]

loopループは、条件じょうけんしきがfalseになるまで、かえ処理しょり実行じっこうします。以下いかは、loopループの構文こうぶんです。

loop
   -- 実行じっこうする処理しょり
end loop;

以下いかは、loopループのれいです。

with Ada.Text_IO; use Ada.Text_IO;

procedure Example is
   I : Integer := 1;
begin
   loop
      Put_Line("I is " & Integer'Image(I));
      I := I + 1;
      exit when I = 5;
   end loop;
end Example;

このれいでは、Iが5になるまで、Put_LineでIの表示ひょうじする処理しょりかえしています。exit whenぶん使用しようして、Iが5になった時点じてんでループを終了しゅうりょうするようにしています。

whileループ

[編集へんしゅう]

whileループは、条件じょうけんしきがtrueのあいだかえ処理しょり実行じっこうします。以下いかは、whileループの構文こうぶんです。

while condition loop
   -- 実行じっこうする処理しょり
end loop;

以下いかは、whileループのれいです。

with Ada.Text_IO; use Ada.Text_IO;

procedure Example is
   I : Integer := 1;
begin
   while I <= 5 loop
      Put_Line("I is " & Integer'Image(I));
      I := I + 1;
   end loop;
end Example;

このれいでは、Iが5以下いかであるかぎり、Put_LineでIの表示ひょうじする処理しょりかえしています。

forループ

[編集へんしゅう]

forループは、初期しょきから終了しゅうりょうまで、指定していされたステップでかえ処理しょり実行じっこうします。以下いかは、forループの構文こうぶんです。

for variable in range loop
   -- 実行じっこうする処理しょり
end loop;

以下いかは、forループのれいです。

with Ada.Text_IO; use Ada.Text_IO;

procedure Example is
begin
   for I in 1..5 loop
      Put_Line("I is " & Integer'Image(I));
   end loop;
end Example;

このれいでは、1から5までの数値すうちを、Iに順番じゅんばん代入だいにゅうしてPut_LineでIの表示ひょうじする処理しょりかえしています。

以下いかは、条件じょうけん分岐ぶんきやループなどの制御せいぎょ構造こうぞうをすべて使用しようした Ada のプログラムれいです。

control_structures.adb
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;

procedure Control_Structures is
   I : Integer;
   Num : Integer;
begin
   -- if-then-else statement
   Put("Enter a number: ");
   Get(Num);
   if Num > 0 then
      Put_Line("The number is positive.");
   elsif Num = 0 then
      Put_Line("The number is zero.");
   else
      Put_Line("The number is negative.");
   end if;

   -- case statement
   Put("Enter a number between 1 and 3: ");
   Get(I);
   case I is
      when 1 =>
         Put_Line("You entered 1.");
      when 2 =>
         Put_Line("You entered 2.");
      when 3 =>
         Put_Line("You entered 3.");
      when others =>
         Put_Line("You entered something else.");
   end case;

   -- for loop
   Put_Line("Printing numbers from 1 to 10:");
   for I in 1..10 loop
      Put(I, 2);
      Put(" ");
   end loop;
   New_Line;

   -- while loop
   I := 1;
   Put_Line("Printing odd numbers from 1 to 10:");
   while I <= 10 loop
      if I mod 2 = 1 then
         Put(I, 2);
         Put(" ");
      end if;
      I := I + 1;
   end loop;
   New_Line;

   -- exit statement
   Put_Line("Printing numbers from 1 to 10 until 6 is reached:");
   for I in 1..10 loop
      if I = 6 then
         exit;
      end if;
      Put(I, 2);
      Put(" ");
   end loop;
   New_Line;

end Control_Structures;

このプログラムでは、ユーザーからの入力にゅうりょくり、if-then-else ぶん使用しようして入力にゅうりょくされた数値すうち符号ふごう判定はんていし、case ぶん使用しようして入力にゅうりょくされた数値すうちによって分岐ぶんきします。 さらに、for ループと while ループを使用しようして、数値すうちかえ出力しゅつりょくし、exit ぶん使用しようしてループからすこともしめしています。

サブプログラム

[編集へんしゅう]

[手続てつづきや関数かんすう宣言せんげん方法ほうほう引数ひきすうわたかたもどあつかいなどを説明せつめいします。]

サブプログラムは、メインプログラムのなか実行じっこうされる独立どくりつしたコードのブロックであり、手続てつづきと関数かんすうの2つの形式けいしきがあります。手続てつづきは、なにかを実行じっこうするためのサブプログラムであり、もどかえさないのにたいして、関数かんすうかえします。

手続てつづきの宣言せんげん

[編集へんしゅう]
procedure Procedure_Name (parameter1, parameter2, ...) is
    -- Declaration statements
begin
    -- Statements
end Procedure_Name;

関数かんすう宣言せんげん

[編集へんしゅう]
function Function_Name (parameter1, parameter2, ...) return Return_Type is
    -- Declaration statements
begin
    -- Statements
    return return_value;
end Function_Name;

引数ひきすうわたかた

[編集へんしゅう]

Adaでは、引数ひきすう参照さんしょうわたし、わたし、および不変ふへんわたしの3つの方法ほうほうわたすことができます。参照さんしょうわたしは、引数ひきすうがサブプログラムない変更へんこうされた場合ばあいもと変数へんすうにも反映はんえいされます。わたしは、引数ひきすうをサブプログラムにコピーするため、もと変数へんすうには影響えいきょうあたえません。不変ふへんわたしは、もと変数へんすう保護ほごするため、サブプログラムない引数ひきすう変更へんこうすることはできません。

れい
procedure Example (A : in Integer; B : out Integer; C : in out Integer) is
begin
    B := A + 1;  -- 変数へんすうBには代入だいにゅうされる
    C := C + 1;  -- 変数へんすうCには代入だいにゅうされ、もと変数へんすうにも反映はんえいされる
end Example;

もどあつか

[編集へんしゅう]

関数かんすうつねかえします。そのため、関数かんすうもど変数へんすう代入だいにゅうすることができます。

れい
function Add (A : Integer; B : Integer) return Integer is
begin
    return A + B;
end Add;

-- メインプログラム
X := Add(2, 3);  -- Xには5が代入だいにゅうされる

オブジェクト指向しこうプログラミング

[編集へんしゅう]

[Adaでのオブジェクト指向しこうプログラミングの基本きほん概念がいねんや、クラスの定義ていぎ方法ほうほう継承けいしょう、ポリモーフィズムなどを説明せつめいします。]

オブジェクト指向しこうプログラミング(OOP)は、プログラムをオブジェクトとばれる単位たんい分割ぶんかつし、それらの相互そうご作用さようによってプログラムを構成こうせいするプログラミングの方法ほうほうろんです。AdaもOOPに対応たいおうしており、以下いか基本きほん概念がいねんやクラスの定義ていぎ方法ほうほうなどを説明せつめいします。

クラスの定義ていぎ方法ほうほう

[編集へんしゅう]

クラスは、データがた定義ていぎ方法ほうほう定義ていぎされます。たとえば、以下いかはクラス Point を定義ていぎするれいです。

-- Pointクラスを定義ていぎ
package Point_Class is
   type Point is tagged record
      X, Y : Integer;
   end record;

   procedure Set_Point(P : in out Point; X, Y : Integer);
   function Get_X(P : Point) return Integer;
   function Get_Y(P : Point) return Integer;
end Point_Class;

クラスの宣言せんげんは、package(パッケージ)ぶんおこなわれます。typeぶんによって、Point という名前なまえのクラスが定義ていぎされ、tagged(タグき)に設定せっていされます。タグきのクラスは、派生はせいがた(クラス)を定義ていぎするさい必要ひつようです。また、recordぶんによって、クラスのメンバーが定義ていぎされます。

つぎに、クラスのメンバーにアクセスするための手続てつづきや関数かんすう定義ていぎします。このれいでは、プロシージャ Set_Point でクラスのインスタンス P のメンバー X と Y に設定せっていし、関数かんすう Get_X, Get_Y でそれぞれの取得しゅとくすることができます。

継承けいしょう

[編集へんしゅう]

Adaは、継承けいしょうをサポートしています。派生はせいがた(サブクラス)は、基底きていがた(スーパークラス)を拡張かくちょうすることができます。たとえば、以下いかはクラス Circle を定義ていぎするれいで、Point クラスを継承けいしょうしています。

-- Circleクラスを定義ていぎ
package Circle_Class is
   type Circle is new Point with record
      Radius : Integer;
   end record;

   procedure Set_Circle(C : in out Circle; X, Y, R : Integer);
   function Get_Radius(C : Circle) return Integer;
end Circle_Class;

typeぶんの new 構文こうぶんで、派生はせいがた Circle が Point クラスを継承けいしょうすることが指定していされています。また、with record で、Circle クラスに独自どくじのフィールド Radius を追加ついかしています。継承けいしょうもとのクラス(スーパークラス)のフィールドは、つづき Circle クラスでも使用しようすることができます。

Adaに多重たじゅう継承けいしょうはありますか?
いいえ、Adaには多重たじゅう継承けいしょうはありません。Adaプログラミング言語げんごは、単一たんいつ継承けいしょう原則げんそく採用さいようしています。これは、あるクラス(Adaでは"がた"とばれる)がのクラスからのみ継承けいしょうできることを意味いみします。これにより、クラスの階層かいそう構造こうぞう簡潔かんけつになり、クラスあいだ複雑ふくざつ関係かんけい減少げんしょうします。

Adaの選択せんたくには、単一たんいつ継承けいしょう理解りかいしやすく、シンプルであるという設計せっけい思想しそう影響えいきょうしています。多重たじゅう継承けいしょう柔軟じゅうなんせい提供ていきょうしますが、クラスの階層かいそう構造こうぞう複雑ふくざつになる可能かのうせいがあり、コードの理解りかいやメンテナンスがむずかしくなることがあるため、Adaは意図いとてきにこれをけています。

わりに、Adaはインターフェースの実装じっそう複数ふくすうのインターフェースのサポート、およびミックスイン(mix-in)のような機能きのう提供ていきょうし、これにより柔軟じゅうなんなオブジェクト指向しこうプログラミングが可能かのうです。

例外れいがい処理しょり

[編集へんしゅう]

[例外れいがい発生はっせいした場合ばあい処理しょり方法ほうほうについて説明せつめいします。]

Adaには例外れいがい処理しょり機構きこうそなわっており、例外れいがい発生はっせいした場合ばあい対処たいしょすることができます。例外れいがいは、実行じっこう発生はっせいするエラーであり、予期よきしない状況じょうきょう発生はっせいした場合ばあい発生はっせいすることがあります。たとえば、ゼロ除算じょざん配列はいれつ境界きょうかいがいアクセス、不正ふせい入力にゅうりょく、メモリ不足ふそくなどがげられます。

例外れいがい処理しょり構文こうぶん以下いかのようになります。

begin
   -- 例外れいがい発生はっせいする可能かのうせいのある処理しょり
exception
   when Exception1 =>
      -- Exception1が発生はっせいした場合ばあい処理しょり
   when Exception2 =>
      -- Exception2が発生はっせいした場合ばあい処理しょり
   ...
   when others =>
      -- 上記じょうき以外いがい例外れいがい発生はっせいした場合ばあい処理しょり
end;

ここで、Exception1やException2は、例外れいがい種類しゅるいしめ例外れいがいめいであり、具体ぐたいてき例外れいがいめいはアプリケーションによってことなります。

例外れいがい処理しょりは、try-catch構文こうぶんのような構造こうぞうであるため、プログラムが例外れいがいをキャッチした場合ばあい該当がいとうする例外れいがい処理しょりブロックが実行じっこうされます。othersキーワードは、上記じょうき例外れいがい以外いがいのすべての例外れいがいをキャッチするために使用しようされます。

以下いかは、例外れいがい処理しょりれいです。

with Ada.Text_IO;
use Ada.Text_IO;

procedure Exception_Handling is
   A : Integer := 10;
   B : Integer := 0;
   Result : Integer;

   -- ゼロ除算じょざん検出けんしゅつする例外れいがい処理しょり関数かんすう
   function Divide(A, B : Integer) return Integer is
   begin
      if B = 0 then
         raise Program_Error;
      else
         return A / B;
      end if;
   end Divide;

begin
   -- Divide関数かんすうでゼロ除算じょざん発生はっせいした場合ばあい
   -- Program_Error例外れいがい発生はっせいするため、例外れいがい処理しょり実行じっこうされる
   begin
      Result := Divide(A, B);
      Put_Line("Result: " & Result'Image);
   exception
      when Program_Error =>
         Put_Line("Error: Division by zero.");
   end;

   Put_Line("End of program.");
end Exception_Handling;

このれいでは、Divide関数かんすうBが0である場合ばあいProgram_Error例外れいがい発生はっせいします。Program_Error例外れいがいは、Adaの標準ひょうじゅん例外れいがいであり、実行じっこうエラーが発生はっせいした場合ばあい自動的じどうてきにスローされます。Divide関数かんすう実行じっこうするために、try-catch構文こうぶん使用しようし、Program_Error例外れいがいをキャッチし、エラーメッセージを表示ひょうじします。

[タスクの定義ていぎ方法ほうほうやスケジューリング、相互そうご排除はいじょなどについて説明せつめいします。]

タスクとは、並行へいこう処理しょり実現じつげんするために使用しようされる概念がいねんです。タスクは、自己じこ完結かんけつがた独立どくりつしたスレッドのようなもので、自分じぶん自身じしん実行じっこう可能かのうであると同時どうじに、のタスクからのメッセージを受信じゅしんして処理しょりおこなうこともできます。タスクのスケジューリングは、Adaランタイムシステムによって自動的じどうてき制御せいぎょされます。

タスクの宣言せんげん方法ほうほうは、以下いかのようになります。

task Task_Name is
   entry Entry_Name (Parameter_List);
end Task_Name;

ここで、Task_Name はタスクの名前なまえ、Entry_Name はタスクからされるエントリーの名前なまえ、Parameter_List はエントリーにわたされる引数ひきすうのリストです。

また、タスクあいだ相互そうご排除はいじょには、以下いかのような手段しゅだんがあります。

  • セマフォ(Semaphore)
  • ミューテックス(Mutex)
  • リモート・リード、ローカル・マルチプル・ライト(Remote_Read, Local_Multiple_Write)

パッケージ

[編集へんしゅう]

[Adaでのパッケージの作成さくせい方法ほうほう使用しよう方法ほうほう名前なまえ空間くうかん機能きのうについて説明せつめいします。]

パッケージは、Adaの名前なまえ空間くうかん実現じつげんするための機能きのうで、関連かんれんするサブプログラムや変数へんすうをまとめることができます。パッケージには、公開こうかいされるインターフェースと、実装じっそうがあります。インターフェースには、のモジュールからアクセス可能かのうなサブプログラムや変数へんすう定義ていぎし、実装じっそうには、これらのサブプログラムや変数へんすう実装じっそう記述きじゅつします。

パッケージの宣言せんげん方法ほうほうは、以下いかのようになります。

package Package_Name is
   -- インターフェース
end Package_Name;

package body Package_Name is
   -- 実装じっそう
end Package_Name;

ファイル入出力にゅうしゅつりょく

[編集へんしゅう]

[ファイルをひらいてきする方法ほうほうについて説明せつめいします。]

Adaにおけるファイル操作そうさは、ストリーム(Stream)とばれる機能きのう使用しようしておこないます。ファイルをひらくには、以下いかのようにします。

with Ada.Text_IO; use Ada.Text_IO;

procedure Main is
   F : File_Type;
begin
   Create (F, Out_File, "output.txt");
   -- 出力しゅつりょくさきのファイルを "output.txt" に設定せってい
end Main;

ファイルからの入力にゅうりょくや、ファイルへの出力しゅつりょくは、Get_Line、Put_Line、Read、Write などのサブプログラムを使用しようしておこないます。

デバッグとテスト

[編集へんしゅう]

[Adaのデバッグやテストの方法ほうほうについて説明せつめいします。]

Adaには、コンパイル静的せいてき検査けんさやランタイム動的どうてき検査けんさなど、様々さまざまなレベルの検査けんさそなわっています。

まず、コンパイル検査けんさについてです。Adaは、かた安全あんぜんせい非常ひじょうたか言語げんごです。静的せいてきがた検査けんさ機能きのうにより、変数へんすう定数ていすうかた一致いっちしない場合ばあい、または初期しょき変数へんすう使用しようした場合ばあいなど、コンパイルにエラーが発生はっせいします。これにより、おおくの実行じっこうエラーを未然みぜん防止ぼうしできます。

ランタイム検査けんさとして、例外れいがい処理しょりがあります。プログラムちゅう発生はっせいする予期よきせぬエラーに対応たいおうするため、例外れいがい処理しょり使用しようすることができます。例外れいがい発生はっせいした場合ばあいは、例外れいがい種類しゅるいおうじた処理しょりおこなうことができます。

また、Adaにはコードカバレッジツールもふくまれています。コードカバレッジツールは、テストちゅう実行じっこうされたコードの割合わりあい測定そくていするために使用しようされます。これにより、どのコードがテストされていないかを特定とくていし、テストの改善かいぜんてんつけることができます。

附録ふろく

[編集へんしゅう]

チートシート

[編集へんしゅう]
with Ada.Text_IO; use Ada.Text_IO;

procedure Subprogram_Cheat_Sheet is
  -- 関数かんすう定義ていぎ
  function Add(a, b : Integer) return Integer is
  begin
    return a + b;
  end Add;

  -- 手続てつづきの定義ていぎ
  procedure Greet(name : in String) is
  begin
    Put("Hello, ");
    Put(name);
    Put_Line("!");
  end Greet;

  -- 引数ひきすうわたかた
  procedure Pass_By_Value(x : Integer) is
  begin
    x := 0; -- 変更へんこうしてももと変数へんすう影響えいきょうはない
  end Pass_By_Value;

  procedure Pass_By_Reference(x : in out Integer) is
  begin
    x := 0; -- 変更へんこうするともと変数へんすうにも影響えいきょうがある
  end Pass_By_Reference;

  -- もどあつか
  function Divide(a, b : Integer) return Float is
    Result : Float;
  begin
    if b = 0 then
      raise Constraint_Error with "Division by zero";
    else
      Result := Float(a) / Float(b);
    end if;
    return Result;
  end Divide;

  -- 例外れいがい処理しょり
  procedure Exception_Handling is
  begin
    Put("Enter an integer: ");
    declare
      Num : Integer := Integer'Value(Get_Line);
    begin
      if Num < 0 then
        raise Constraint_Error with "The number must be non-negative";
      else
        Put("The square root of ");
        Put(Num, Width => 0);
        Put(" is ");
        Put(Float'Sqrt(Float(Num)), 2);
        New_Line;
      end if;
    exception
      when Constraint_Error =>
        Put_Line("Error: " & Exception_Message);
    end;
  end Exception_Handling;

begin
  -- テスト
  Put_Line("Add(1, 2) = " & Integer'Image(Add(1, 2)));
  Greet("Alice");

  -- 引数ひきすうわたかた
  declare
    x : Integer := 1;
  begin
    Pass_By_Value(x);
    Put_Line("x = " & Integer'Image(x)); -- 1
    Pass_By_Reference(x);
    Put_Line("x = " & Integer'Image(x)); -- 0
  end;

  -- もどあつか
  Put_Line("Divide(4, 2) = " & Float'Image(Divide(4, 2)));
  Put_Line("Divide(4, 0) = " & Float'Image(Divide(4, 0))); -- Constraint_Error

  -- 例外れいがい処理しょり
  Exception_Handling;
end Subprogram_Cheat
with Ada.Text_IO; use Ada.Text_IO;

procedure OOP_Cheat_Sheet is

   -- クラスの定義ていぎ
   type MyClass is tagged record
      x: Integer;
   end record;

   -- クラスの継承けいしょう
   type MySubclass is new MyClass with record
      y: Integer;
   end record;

   -- ポリモーフィズム
   type MyClass_Access is access all MyClass'Class;
   procedure MyProc (Obj : MyClass_Access'Class);

   -- クラスメソッド
   function Get_X (Obj : MyClass'Class) return Integer is
   begin
      return Obj.x;
   end Get_X;

   -- クラスの操作そうさ
   procedure Set_X (Obj : in out MyClass'Class; Val : Integer) is
   begin
      Obj.x := Val;
   end Set_X;

   -- クラスの初期しょき
   overriding procedure Initialize (Obj : in out MyClass'Class) is
   begin
      Obj.x := 0;
   end Initialize;

   -- クラスの終了しゅうりょう処理しょり
   overriding procedure Finalize (Obj : in out MyClass'Class) is
   begin
      null;
   end Finalize;

   -- クラスの利用りようれい
   Obj : MyClass'Class := new MyClass;
begin
   Set_X (Obj, 42);
   Put_Line (Integer'Image (Get_X (Obj)));
end OOP_Cheat_Sheet;

用語ようごしゅう

[編集へんしゅう]
  1. パッケージ(package):関連かんれんするサブプログラムやかた定数ていすうなどをひとまとめにした、独立どくりつしたコンパイル単位たんい。パッケージ仕様しようとパッケージ本体ほんたいかれる。
  2. タイプ(type):データの種類しゅるい定義ていぎする。整数せいすうがた浮動ふどう小数点しょうすうてんがた文字もじがたなどがある。かた定義ていぎには、レコードがた配列はいれつがたなども使用しようできる。
  3. モジュール(module):Adaプログラムの構成こうせい単位たんい複数ふくすうのパッケージやサブプログラムから構成こうせいされ、単一たんいつのコンパイル単位たんいとなる。
  4. サブプログラム(subprogram):かえ使つかわれる処理しょりをまとめた、関数かんすう手続てつづきなどの部品ぶひん関数かんすうかえし、手続てつづきはかえさない。
  5. 引数ひきすう(parameter):サブプログラムにあたえる入力にゅうりょく。サブプログラムないでのみ使用しようできる変数へんすうであり、もと変数へんすう影響えいきょうあたえない。
  6. 例外れいがい(exception):プログラムの実行じっこうちゅう発生はっせいするエラーを処理しょりするためのメカニズム。例外れいがい発生はっせいした場合ばあいは、例外れいがい処理しょり部分ぶぶん制御せいぎょうつる。
  7. 継承けいしょう(inheritance):オブジェクト指向しこうプログラミングにおける、あたらしいクラスの定義ていぎ既存きそんのクラスをもとにしてあらたな機能きのう追加ついかする仕組しくみ。
  8. ポリモーフィズム(polymorphism):オブジェクト指向しこうプログラミングにおける、ことなるクラスのオブジェクトをおなじインタフェースであつかうことができる性質せいしつ
  9. タスク(task):並列へいれつ処理しょり実現じつげんするための機能きのう。Adaでは、タスクの生成せいせい同期どうき通信つうしんなどをおこなうことができる。
  10. ファイル(file):外部がいぶ記憶きおく装置そうち格納かくのうされたデータをあつかうためのデータがた。ファイルをオープンすることで、ファイルからの入力にゅうりょくやファイルへの出力しゅつりょく可能かのうになる。
  11. 名前なまえ空間くうかん(namespace):名前なまえ衝突しょうとつ回避かいひするための仕組しくみ。パッケージの名前なまえ空間くうかんは、パッケージない定義ていぎされます。