H-3 第3章の相違点

型の名前

Delphi における型の名前と C++Builder における型の名前は、次のように対応しています。

Delphi C++Builder
Integer int
Real double (float という型もあるが、滅多に使われない)
String AnsiString

型変換

型変換は次の通りです。

型変換の種類 Delphi C++Builder
整数型から文字列型へ IntToStr() (命令がなくても自動的に変換される)
文字列型から整数型へ StrToInt() ToInt()
実数型から文字列型へ FloatToStr() 又は FloatToStrF() (命令がなくても自動的に変換される)
文字列型から実数型へ StrToFloat() ToDouble()
整数型から実数型へ (命令がなくても自動的に変換される) (命令がなくても自動的に変換される)
実数型から整数型へ Ceil(), Floor(), Round(), Trunc() (命令がなくても自動的に切捨てとなる)

また、C++ には文字型 (1文字しか保持できない変数の型) という型があり、char 型と呼ばれています(同様の型は Delphi にもありますが、Delphi では String 型を用いることが多いようです)。 C++ では、この char 型を配列にして文字列を扱うことも多々あり、引数として char 型の配列を要求する関数も少なくありません。このような場合、AnsiString 型の変数に c_str() というメソッドを使って char 型の配列にすることが出来ます。

Edit1.Text AnsiString
Edit1.Text.c_str() char 型の配列

大文字・小文字の区別

大文字・小文字が同一視される Delphi とは異なり、C++ では大文字と小文字が区別されます。つまり、Edit1edit1 という2つの記述があったら、Delphi では同じコンポーネントを指し、C++ では違うコンポーネントを指します。

コメント

Delphi では

がコメントとして無視されます。これが C++ では

がコメントとして無視されます。

変数宣言

例えば、temp という文字列型変数を用意する場合、Delphi では begin の前に

var
  temp: String;

と宣言しますが、C++ ではその変数を実際に使う直前 (又はもっと前でもよい) に

AnsiString temp;

と宣言します。そのため、【基礎課題 3-7】は Delphi では

procedure TForm1.ButtonChangeClick(Sender: TObject);
var
  temp: String;
begin
  temp := Edit1.Text;
  Edit1.Text := Edit2.Text;
  Edit2.Text := temp;
end;

となりますが、C++Builder では

void __fastcall TForm1::ButtonAddClick(TObject *Sender)
{
  AnsiString temp;
  temp = Edit1->Text;
  Edit1->Text = Edit2->Text;
  Edit2->Text = temp;
}

となります。また、

void __fastcall TForm1::ButtonAddClick(TObject *Sender)
{
  AnsiString temp = Edit1->Text;
  Edit1->Text = Edit2->Text;
  Edit2->Text = temp;
}

というように「変数の宣言」と「変数の初期化」を同時に行うことも可能です。

整数の除算でも /

Delphi では、整数の除算は div、実数の除算は /、と使い分けることになっていましたが、C++ では整数でも実数でも / を使います。そのため、3-9 の【練習問題】

procedure TForm1.ButtonAddClick(Sender: TObject);
var
  a: Integer;
  b: Integer;
  c: Integer;
begin
  a := StrToInt(Edit1.Text);
  b := StrToInt(Edit2.Text);
  c := (a + b) / 2;
  EditResult.Text := IntToStr(c);
end;

は、Delphi ではエラーが出て止まってしまいますが、これを C++Builder 用に

void __fastcall TForm1::ButtonAddClick(TObject *Sender)
{
  int a = Edit1->Text.ToInt();
  int b = Edit2->Text.ToInt();
  int c = (a + b) / 2;
  EditResult->Text = c;
}

と書き換えた場合、C++ では整数の除算にも / を用いるためエラーが発生しません。ただし、このままでは小数点以下が無視されるため、実際には

void __fastcall TForm1::ButtonAddClick(TObject *Sender)
{
  int a = Edit1->Text.ToInt();
  int b = Edit2->Text.ToInt();
  double c = (a + b) / 2.0;
  EditResult->Text = c;
}

としなくてはプログラムが正しく動作しません。

コラム なぜ 2 ではなく 2.0 なのか

このプログラムで最初は (a + b) / 2 だった部分が、最後には (a + b) / 2.0 になっています。これは、ab2 も全て整数型であるため、C++Builder は (a + b) / 2 の式の中の / を「整数型の除算」と見なし、その答も整数型にしてしまうためです。これを避けるために、式の一部分 (この場合は 2) を実数型 (この場合は 2.0) にしてしまうことで、/ を「実数型の除算」として扱わせることが出来ます。

文字列型定数

Delphi では、文字列型定数は ' で括る事になっていました。C++ では文字列型定数は "で括ります。例えば【基礎課題 3-15】は、Delphi では

procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit2.Text := Edit1.Text + 'さん';
end;

と書きましたが、C++Builder では

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  Edit2->Text = Edit1->Text + "さん";
}

と書きます。

様々な演算子

C++ には、次の演算子があります。

Delphi での書き方 C++ での基本的な書き方 C++ での別の書き方
a := a + b a = a + b a += b
a := a - b a = a - b a -= b
a := a * b a = a * b a *= b
a := a / b a = a / b a /= b

更に、1だけ増やしたり減らしたりする時は、次のような書き方が出来ます。

Delphi での書き方 C++ での基本的な書き方 C++ での別の書き方 C++ での更に別の書き方
a := a + 1 a = a + 1 a += 1 a++ 又は ++a
a := a - 1 a = a - 1 a -= 1 a-- 又は --a

なお、この表の「C++ での基本的な書き方」は、実際には滅多に使われず、「別の書き方」や「更に別の書き方」が用いられます。

メモの各行へのアクセス

Delphi では、メモの各行へアクセスする場合、Memo1.Lines[0], Memo1.Lines[1], …とアクセスできましたが、C++Builder では Memo1->Lines->Strings[0], Memo1->Lines->Strings[1], …という (Strings まで含めた) 本来の書き方でないとアクセスできません。