変数の宣言に始まり、条件分岐や繰り返しなどを記述するステートメント。C#のそれは大部分がCやC++からの流用だが、より磨きがかけられている。
本記事は、(株)技術評論社が発行する書籍『新プログラミング環境 C#がわかる+使える』から許可を得て転載したものです。同書籍に関する詳しい情報については、本記事の最後に掲載しています。
古い世代のプログラミング言語では、すべての機能を言語仕様に取り込んでしまうことが多かった。その後、入出力などの機能は言語の一部としてではなく、ライブラリに置く方向に進化してきた。そのため、BASICではステートメントとして言語の一部であった多くの機能がライブラリに移動し、C#ではステートメントの種類は大幅に減少している。ステートメントとして残ったものは、ライブラリでは実現できない最小限のものに限られている。しかし、種類は少ないものの、条件判断や繰り返しなどよく使われるものが多いので、習得は必須といえる。本章ではC#の主要なステートメントを解説する。
C#で最も基本となるステートメントがブロックである。ブロックは複数のステートメントを集めて1つのステートメントであるかのように見せかける機能を持つ。これにより、1つのステートメントに作用する機能に対して、複数のステートメントを与えることが可能になる。例えば、後で述べるifステートメントでは、条件成立時に実行できるステートメントは1個だけだが、その1個をこのブロック・ステートメントにすれば、何個でもステートメントを実行させることができる。いちいち説明しないがほかのステートメントでも同様である。
ブロック・ステートメントの構文は簡単で、「{」記号で始まり、「}」記号で終わるだけである。
ブロック・ステートメントはローカル変数の寿命に影響を与えることに注意が必要である。List 9-1のサンプル・ソースを見ていただきたい。
1: using System;
2:
3: namespace Sample001
4: {
5: class Class1
6: {
7: [STAThread]
8: static void Main(string[] args)
9: {
10: int a=1;
11: {
12: int b=2;
13: Console.WriteLine(a);
14: Console.WriteLine(b);
15: }
16: Console.WriteLine(a);
17: // Console.WriteLine(b); // 名前 'b' は クラスまたは名前空間 'Sample001.Class1' に存在しません。
18: }
19: }
20: }
このサンプル・ソースを実行した結果はFig.9-1のようになる。
なお、同じ名前の変数を1つのメソッド内で宣言しようとすると、紛らわしい場合がある。そのような場合はエラー扱いになることもある。詳しくは、本章末のコラム「スコープと変数」で解説している。
話は前後するが、ローカル変数を宣言することも一種のステートメントとして扱われている。すでに何回も使ってきた機能なので、あらためてくどくど説明することもないだろう。
宣言する際に、手前にconstキーワードを付加すると、ローカル変数ではなく、ローカル定数となる。定数は値を決めたらいっさい変更できないものである。サンプル・ソースList 9-2の10行目がローカル変数の宣言、11行目がローカル定数の宣言になる。ローカル変数は12行目のように値を変更できるが、ローカル定数は13行目のように値を変更するコードを書くとコンパイル・エラーになる。
1: using System;
2:
3: namespace Sample002
4: {
5: class Class1
6: {
7: [STAThread]
8: static void Main(string[] args)
9: {
10: int i=1;
11: const int j=1;
12: i = i + 1;
13: // j = j + 1; // 代入式の左辺には変数、プロパティ、またはインデクサを指定してください。
14: Console.WriteLine(i);
15: Console.WriteLine(j);
16: }
17: }
18: }
このサンプル・ソースを実行した結果はFig.9-2のようになる。
変えられない値を扱う方法には、もう1つreadonlyキーワードを使う方法もある。詳細は、本章末のコラム「constとreadonly」を参照されたい。
条件によって実行するステートメントを変える手段は2つある。1つはifステートメントによる条件判断であり、条件判断式が成立したときと成立しないときで処理内容を分けることができる。もう1つはswitchステートメントで、式の値によって処理を分けることができる。List 9-3はそれを示したサンプル・ソースである。
1: using System;
2:
3: namespace Sample003
4: {
5: class Class1
6: {
7: [STAThread]
8: static void Main(string[] args)
9: {
10: if( args.Length != 0 )
11: {
12: Console.WriteLine("yes args");
13: }
14: else
15: {
16: Console.WriteLine("no args");
17: }
18: switch( args.Length )
19: {
20: case 0:
21: Console.WriteLine("no args");
22: break;
23: default:
24: Console.WriteLine("yes args");
25: break;
26: }
27: switch( args.Length )
28: {
29: case 0:
30: Console.WriteLine("args=0");
31: break;
32: case 1:
33: Console.WriteLine("args=1");
34: goto case 2;
35: case 2:
36: Console.WriteLine("args=2");
37: goto default;
38: default:
39: Console.WriteLine("yes args");
40: break;
41: }
42: switch( args[0] )
43: {
44: case "hello":
45: Console.WriteLine("hello!");
46: break;
47: default:
48: Console.WriteLine("not hello!");
49: break;
50: }
51: }
52: }
53: }
このサンプル・ソースを実行した結果はFig.9-3のようになる。
10行目のifの条件式に書かれた「args.Length」は、コマンドライン引数に何個の値が書かれているかを示すプロパティである。つまり、コマンドラインからこのサンプル・ソースを実行するときに、何か文字列を付け加えなければプロパティの値はゼロになり、付け加えたらその個数を値として持つ。ここでは条件判断の動きを見るために使ったもので、深い意味はない。
10行目のifは、「args.Length != 0」、つまり、コマンドラインに何か書いてあれば12行目を実行し、そうでなければ16行目を実行する。11〜13行目と15〜17行目の「{」と「}」はブロック・ステートメントである。
18行目のswitchは括弧内の値とその後のcaseの後の値を比較し、一致したらcase以後のステートメントを実行する。つまり、「args.Length」の値がゼロなら、20行目の「case 0」が成立して、21〜22行目が実行される。caseは何個でも書くことができるが、いずれにも合致しない場合は「default:」以後が実行される。つまり、この場合は「args.Length」の値がゼロ以外のときは、24〜25行目が実行される。
さて、switchステートメントの中で使用されるbreakは、処理を終了してswitchステートメントから抜け出す機能を持ったキーワードである。breakが出現すると、そこで処理は打ち切られてswitchステートメントの次のステートメントが実行される。このとき、処理を終了させるのではなく、別のcaseの条件の処理に飛ばしたい場合がある。そのような場合は、breakの代わりに「goto case」という構文を使う。34行目がそれを使った実例である。「args.Length」が1のとき、33〜34行目が実行されるが、34行目の「goto case 2」によって、「case 2」へ制御が移り、36〜37行が実行される。37行に書かれた「goto default」は「default」へ制御を移す機能を持っていて、これによりさらに39〜40行目が実行され、40行目の「break」によって、やっとswitchステートメントから出ることになる。
ここで、C/C++プログラマーは注意してほしいのだが、C#では、breakまたはgotoを用いないで次のcaseの処理にそのまま入って行くことは許されない。そのような処理が必要な場合は、「goto case」を用いて、明示的に次に処理すべき先を指定しなければならない。似てはいるが異なっている部分なので注意が必要だ。
C#のswitchステートメントは、文字列(string)を扱うこともできる。42〜50行のswitchステートメントがその実例を示す。42行目の「args[0]」は、コマンドラインの引数に書かれた最初の文字列を示す(ここにはエラー・チェックのコードが入っていないので、もし引数なしでこれを実行すると42行目で例外が発生して停止することを付記しておく)。「args[0]」の値がhelloなら、45〜46行目が実行される。それ以外の文字列なら48〜49行目が実行される。
Copyright© Digital Advantage Corp. All Rights Reserved.