変数--値を保存する場所

わり算はある意味でたし算、ひき算、かけ算より格段にむつかしくて、たし算、ひき算、かけ算を全部含んでいますから、わり算をしっかり練習すれば、ほかはある程度、自然に練習ができてしまいます。

『数学の学び方・教え方』遠山啓著より引用

変数を理解するには、まず「型」について知らなければならない。型とはなんだろうか。試しに辞書で引くと、次のような記述が見つかる:

  1. 物の姿や格好。形状。かたち
  2. 事物を類別するとき、その個々に共通した特徴を表している形式、形態。タイプ

2. が、ここで述べたい型についてよく表している。

値は型をもつ。値とは、3 とか 1.23 とか 'Hello, world' などのことだ。3 は「整数型」、1.23 は「実数型」、'Hello, world' は「文字列型」の型をもつ。

    
1, 20, 100 整数型
1.2, 0.12実数型
'foo', 'bar' 文字列型

つまり、整数の型は整数型、実数の型は実数型、文字列(シングルクォートで囲まれた文字の列)の型は、文字列型ということになる。上の 2. が述べているように、個々の値に共通した特徴を表したものを型と呼んでいる。

変数には値を代入できる。しかし代入できる値は、その変数の型と同じでなければならない。

var
  x: Integer;
begin
  x := 10;
  Writeln(x);
  Readln;
end.
10

変数への値の代入は、上のコードのように := を使う。これは「:= の左辺の変数に右辺の値を代入する」と読む。すなわち、

x := 10;

は、「変数 x に、値 10 を代入する」となる。ちなみに := のことを代入演算子と呼ぶ。

忘れてならないのは、変数の宣言である。コードの中で使用される変数は、前もって宣言されていなくてはならない。その宣言場所が、var だ。var は begin よりも前(上)に書く、そして var から begin までの間に変数宣言を書く。宣言の仕方は次のようになる:

<変数名>: <変数の型>;

最初のコードでは、

x: Integer;

となっていたが、これは <変数名> が x で <変数の型> が Integer ということになる。Integer は整数型を表す。カンマを使って、複数の変数を並べて宣言することもできる。

 x, y, z: Integer;

これは、3 つの変数 x, y, z が Integer 型であることを表す。次のコードを実行してみよう。

var
  x, y, z: Integer;
begin
  x := 10;
  y := 2;
  z := x + y;
  Writeln(z);
  
  Readln;
end.
12

このコードは、まずはじめに変数 x に 10 を代入している。その次に変数 y に 2 を代入している。それから変数 x に代入された値と、変数 y に代入された値とで足し算を行い、その結果を変数 z に代入している。変数 x には 10 が、変数 y には 2 が代入されているので、変数 z には 12 が代入されることになる。

文字列は、シングルクォートで挟まれた文字の列のことだ。文字列型は string で表される。

var
  s: string;
begin
  s := 'Introduction';
  Writeln(s);

  Readln;
end.
Introduction

変数 s に文字列 'Introduction' を代入し、そしてそれを出力している。文字列を「文字の列」といったことに注目しよう。文字の列なんだから、何番目かの「文字」を出力することもできる。

var
  s: string;
begin
  s := 'Introduction';
  Writeln(s[1]);
  Writeln(s[2]);
  Writeln(s[3]);

  Readln;
end.
I
n
t
s[1]

のようにして、整数番目の文字を取得できる。s[1] の 1 のことは添え字と呼ばれる。1 番目が文字の先頭だ。

文字が取得できるのだから、当然「文字型」もある。

var
  s: string;
  c, d: Char;
begin
  s := 'Gowers';
  c := s[1];
  d := 'G';

  Writeln(s);
  Writeln(s[1]);
  Writeln(c);
  Writeln(d);

  Readln;
end.
Gowers
G
G
G

文字型は、Char で表される。文字と文字列は同じではなく、別物として扱われる。これからは「文字」と「文字列」という言葉を使い分けていくので注意しよう。文字列はシングルクォートで囲むと述べた。文字も同様にシングルクォートで囲む。文字列と文字、どちらもシングルクォートを使う。囲まれた文字が 1 つなら文字、2 つ以上なら文字列になると思えばいい。

文字(列)同士は、+ 演算子を使って足し算することができる。

var
  s, s2, s3: string;
begin
  s := '60 miles';
  s2 := ' an hour';

  s3 := s + s2;
  Writeln(s3);
  Writeln(s + s2);
  Writeln(s + ' an hour');
  Writeln('60 miles' + s2);

  Readln;
end.
60 miles an hour
60 miles an hour
60 miles an hour
60 miles an hour

このように文字(列)同士は足し算できる。文字列同士の加算結果は、それらを連結した文字列となる。では、文字列の引き算はどうなるだろうか。

var
  s: string;
begin
  s := 'foo' - 'bar';
  Writeln(s);
  Readln;
end.

このコードを実行しようとすると、次のエラーが表示されるはずだ:

[エラー] この型には指定した演算子は使えません

つまり、文字列同士の引き算は出来ないということだ。

考えを広げるために

文字列同士の足し算は、その文字列の連結となることが分かった。また、文字列同士の引き算は出来ない(エラーとなる)ことが分かった。では、文字列同士の掛け算はどうなるだろうか?

あなたが講座を読み進める際、ページ内では触れていない(解説されていない)が、あなた自身が疑問に思うことがいくつか出てくると思う。そういった疑問は、疑問のまま頭の中を素通りさせずに、実際にコードに書き下してみることをお勧めしたい。どんな小さなことでも構わない。ただ解説を読むだけよりもずっと理解が深まる(し、楽しい)と思う。

変数には、その変数の型と同じ値しか代入できないと述べた。だから文字列型の変数には、文字列しか代入できない。文字列型の変数に、もし整数を代入するようなコードを書いたとしたらどうなるだろうか。

var
  s: string;
begin
  s := 120; // 文字列型の変数 s に 整数型の値 120 を代入しようとしている [マチガイ]
  Writeln(s);

  Readln;
end.

F9 キーを押してプログラムを実行しようとすると、こんなエラーが表示されるはずだ:

String と Integer には互換性がありません。

これは「文字列型として宣言された変数に、整数型を代入することはできない」という意味のエラーである。繰り返すが、変数の型と変数に代入しようとする値の型は、同じでなくてはならない(より正確には、互換性がなければならない)。

文字型の変数に文字列を代入しようするときも、同様にエラーとなる。

var
  c: Char;
begin
  c := 'very short'; // エラー

  Readln;
end.

次のエラーメッセージが表示される:

Char と String には互換性がありません。

しかし、文字は文字列型の変数に代入できる:

var
  c: Char;
  s: string;
begin
  c := 'H'; 
  s := c; // 文字を文字列型の変数に代入
  Writeln(s);

  Readln;
end.
H

アンフェアな感じがするかもしれないが、文字は文字列型の変数に代入できる。しかし逆は出来ない。さっき見たように、文字列を文字型の変数に代入する事はできない。

大事なことをおさらいしよう。

関数を呼び出す

関数とは何か。関数とは自動販売機だと考えると分かり易い。あなたがお金をコイン投入口から入れる。するとジュースが出てくる。つまり入力としてお金を入れたら、出力としてジュースが出てきたというわけだ。関数も似たようなもので、関数に入力を与えると、出力が返ってくる。次のコードでは Max 関数を呼び出している。Max 関数は、2 つの整数を入力とする。入力として与えた 2 つの値の大きい方が出力として返ってくる。

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils, Math; // Math を追加

var
  x: Integer;
begin
  x := Max(20, 100);
  Writeln(x);

  Readln;
end.
100

ここでは、コードを全文載せた。uses の所に Math を追加するのを忘れないように。

x := Max(20, 100);

この行の

Max(20, 100);

という部分に注目する。これは、Max という関数の呼び出しである。Max を自動販売機だと考える。入力として 2 つの整数を与えたとき、Max 自動販売機は入力として与えられた 2 つの整数のうちで大きい方の値を出力として返す。

もう一度最初からコードをみる:

Max(20, 100);

入力として 2 つの整数(20 と 100)を与えると述べたが、この入力値のことを引数(ひきすう)、又はパラメータと呼ぶ。引数とは関数に渡される値のことだと考えるようにしよう。出力のことも言い直すと、関数の戻り値(返り値)と呼ぶのが正しい。もう一度見直そう:

Max(20, 100);

Max 関数の引数は整数 20 と 100 の 2 つだ。それぞれの引数はカンマで区切る。渡された引数のうち大きい値が Max 関数の戻り値となる。

x := Max(20, 100);

これは、Max 関数の戻り値を変数 x に代入する。よって変数 x には 100 が代入されることになる。

次は、Min 関数についてみよう。Min 関数は 2 つの引数をとり、戻り値として引数の小さい値のほうを返す。

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils, Math;

var
  x: Integer;
begin
  x := Min(20, 100);
  Writeln(x);

  Readln;
end.
20
  x := Min(20, 100);

Min 関数を引数 20 と 100 で呼び出す。Min 関数は引数として渡された整数の小さい方の値を返す。つまり Min 関数は 20 を返す。よって変数 x には 20 が代入される。

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils, Math;

var
  x: Integer;
begin
  x := Abs(-20);
  Writeln(x);

  Readln;
end.
20

関数 Abs を引数 -20 で呼び出している。関数 Abs は引数の絶対値を返す関数である。

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils, Math;

var
  x, y: Integer;
begin
  x := -20;
  y := Max(4, Abs(x));
  Writeln(y);

  Readln;
end.
20

Max 関数の 2 つの引数は、4 と Abs(x) の戻り値である。Abs(x) の戻り値は、変数 x に代入されている値の絶対値であるから、結果として Max 関数は大きい値のほうの 20 を返す。その 20 が変数 y に代入される。

これまでに何度も使用してきた Writeln も Readln も同様に関数である。しかし、これらは値を返さない関数だ。詳しくは「関数」の所で説明する。

最後に IntToStr 関数と StrToInt 関数についてみていこう。IntToStr 関数は一つの引数をとる関数である。引数の型は整数でなければならない。IntToStr 関数は受け取った整数を文字列に変換して、返す。

var
  s: string;
begin
  s := IntToStr(100);
  Writeln(s);
  Writeln(s + '10');

  Readln;
end.
100
10010
s := IntToStr(100);

IntToStr 関数は、引数を 100 として呼び出される。IntToStr 関数は、受け取った整数を文字列に変換し、それを返す。よって変数 s には文字列 '100' が代入される。

var
  x: Integer;
  s: string;
begin
  x := 123;
  s := IntToStr(x);
  Writeln(s + '456');
  Writeln(x + 456);

  Readln;
end.
123456
579

IntToStr 関数に変数 x を渡して呼び出している。よって変数 s には文字列 '123' が代入される。

次に StrToInt 関数をみよう。

var
  s: string;
begin
  s := '102';
  Writeln(StrToInt(s) + 8);
  Writeln(s + '8');

  Readln;
end.
110
1028

StrToInt 関数は文字列型の引数を整数に変換して返す。

StrToInt(s) + 8 

は整数同士の足し算だ。一方、

s + '8'

は文字列同士の足し算となる。

StrToInt 関数は文字列を整数に変換して、それを返すと説明した。文字列は、いつでも整数に変換できるわけではない。整数に変換できる文字列しか整数に変換できない。もし、StrToInt 関数に整数に変換できない文字列を渡したとすると、エラーが発生する。

var
  s: string;
  x: Integer;
begin
  s := 'a';
  x := StrToInt(s);
  Writeln(x);

  Readln;
end.

文字列 'a' を整数に変換しようとするコードだ。このコードを実行すると、次のようなダイアログが表示される。

プログラムを終了させるには、メニュー欄から [ 実行 | プログラムの終了 ] を選択する

「例外」が発生すると、このようなダイアログが表示される。例外とはなにか。それを知るにはクラスについてまず知らなければならない。クラスについて学ぶということは、将棋でいうところの”穴熊”を学ぶことに相当する。いまわれわれは、歩や桂馬などの駒がどんな動き方を学んでいる最中なのだから、穴熊を理解するのは後のお楽しみにとっておくことにしよう。

例外はエラーが発生したときに生成されると考えていい。表示されたダイアログに、そのエラーメッセージが書いてある:

'a' は整数ではありません

文字列 'a' は整数に変換することは出来ない。だからエラーが発生したのだ。

プログラムを実行するとき、これまでは F9 キーを押して実行していた。F9 キーを押すと何が起こるのか。ごく簡単に解説すると F9 キーを押すとコンパイルという処理が行われる。その処理の 1 つに、あなたがエディタに書いたプログラムが Delphi 言語の文法として正しいかどうかのチェック作業がある。プログラムが文法的に正しくなければ、エラーが報告される。このエラーのことを、コンパイルエラーと呼ぶ。プログラムが文法的に正しければ、今度はそのプログラムの機械語への翻訳作業がある。といってもコンパイルと翻訳作業がきっちりと分けられているわけではなく、コンパイルという言葉に翻訳作業という意味も含まれているので、それらに明確な境界線はない。文法チェックをしながら翻訳作業も行っているというような感じだ。翻訳作業が無事終わると、ようやくそこからプログラムの実行が始まる。例外が発生するのはプログラム実行時だ。だから実行時エラーなんて呼ばれたりする。プログラム実行時に生じたエラーは、実行時エラーとなり、コンパイル中に生じたエラーは、コンパイルエラーとなる。

最後に、変数についてのまとめをもう一度:


up next

更新日:2005-01-15