D言語入門 第13章 - その他の文法1
#01 - with文
今回は…
以前構造体を使用しましたね。
今回は、その構造体のメンバを一気にまとめて変更したい場合なんかに有効な文法 with 文を紹介します。
この文法はC言語には存在しません。
このキーワードが存在する言語としては、JavascriptをはじめとするECMAScript系の言語なんかが有名ですね。
今回のミソ
- with(構造体の変数){ 処理 }
- 上の処理のところでは、構造体の変数の名前を使用しなくてもその構造体の中身にアクセスできる
サンプルコード
import std.stdio;
struct MyStruct
{
int a;
int b;
int c;
int x;
int y;
int z;
}
int main(char[][] args)
{
MyStruct mystruct;
with (mystruct)
{
a = 10;
b = 20;
c = 30;
x = a*4;
y = b*5;
z = c*6;
}
with (mystruct)
{
writefln("a = %d", a);
writefln("b = %d", b);
writefln("c = %d", c);
writefln("x = %d", x);
writefln("y = %d", y);
writefln("z = %d", z);
}
return 0;
}
実行結果
a = 10
b = 20
c = 30
x = 40
y = 100
z = 180
まとめ
というわけで、with文。使いどころが難しいかもしれませんが、使えるところでは使えますよ。
具体的には、もっと先でやるclassのメソッドやプロパティと呼ばれるものにもアクセスできたりするので、オブジェクト指向向きの文法と言えます。
今のところは構造体をもっと使いやすくする方法という感じで覚えておくといいかもしれませんね。
#02 - switch文
今回は…
switch文を説明します。これは条件分岐の一種の文法です。なので、ifやelseを使用しても同じ挙動が期待できる場合が多いです。
ただ、switch文は、C言語にも存在する割とベーシックな文法です。いろいろなところで見るかと思いますので、一応触れておきます。
if文で十分に代用可能な文法ですが、もしかしたら最適化が計れて速度的に有利になることがあるかもしれません。あまり期待はできないけど。
特に、Windowsプログラミングにおけるウィンドウプロシージャの内部処理には頻繁に登場する文法です。
個人的にはswtich文の文法が若干気味悪く感じるのでifを使うことのほうが多いですが…
今回のミソ
- switch(式){ 分岐 } を使うと多条件分岐になる。
- 分岐には case文とdefault文を使う
- 式 が case 値: の値になった場合、そこへ飛ぶ。
- 式 が複数ある case 値: のどの値にも当てはまらなかった場合、 default: へ飛ぶ。
- 終わる場合は break を使う。
- breakしないcase文はその次のcase文もつづけて実行する。
-
switch (式)
{
case(値1):
式が値1だったときの処理;
break;
case(値2):
式が値2だったときの処理;
break;
default:
デフォルトの処理;
}
- (上のような感じなのですが、わかりにくいと思うのでサンプルを見ましょう)
サンプルコード
import std.stdio;
void Switching(int x)
{
switch(x)
{
case(0):
writefln("零の場合");
break;
case 1:
writefln("一の場合");
break;
case(2):
writefln("二の場合。breakがないので次のも実行。");
case(3):
writefln("三の場合");
break;
default:
writefln("デフォルトの挙動");
}
}
int main(char[][] args)
{
Switching(0);
Switching(1);
Switching(2);
Switching(3);
Switching(4);
return 0;
}
実行結果
零の場合
一の場合
二の場合。breakがないので次のも実行。
三の場合
三の場合
デフォルトの挙動
まとめ
switch文は使いどころが限られます。正直ifのほうが使いやすかったりもします。
ただ、何度も if(x == 1){ ... }else if(x == 2){ ... } といったように x == ... のような似たような条件を繰り返して使いたくない場合に使うといいと思います。
………ほかにswtichの有用性について知っている方がいたら教えてください>
ここから
#03 - foreach文
今回は…
foreach文です。foreach文は繰り返し構文の一種です。
foreach文はC言語では使用できません。利用できる言語は
Wikipediaを見るといいでしょう
foreach文は配列などに関して、すべての要素に対して処理を行う場合に非常に便利な文です。
配列など、というのは他にも使えるものがあって、ある特定の条件を満たした構造体、クラス、連想配列にも使うことができるます。これらはのちの講座で解説します。
今回のミソ
- foreach(val;list){ ... }
- valはlistの中のデータが一つずつ入る
- foreach文を使うと、breakするかすべての要素をめぐるまでループする
- valは型名などを使ってもよいが、使わなくても勝手に推測してくれる
- foreach(ref val;list){ ... } とすると、リストの要素の変更が可能
サンプルコード
import std.stdio;
int main(char[][] args)
{
int[5] list;
list[0] = 4;
list[1] = 3;
list[2] = 2;
list[3] = 5;
list[4] = 7;
foreach (val; list)
{
writefln(val);
}
foreach (ref val; list)
{
val = 8;
}
foreach (i,ref val; list)
{
val = i + val + list[ (i+4) % list.length ];
}
foreach (val; list)
{
writefln(val);
}
return 0;
}
実行結果
4
3
2
5
7
16
25
35
46
58
まとめ
さてforeachもswitch同様forやwhile文で同じものが記述できます。
では、いったい何がいいのか。
まず、その一つとして、このような配列をすべて廻るようなものでは添え字が配列に対して大きすぎる値を入力することが少なくなります。バグの原因を減らせます。
ほかにも、簡単な記述が可能ということや、限定された使い方であるため最大の効率化が期待できたりもします。(これもやはりあまり期待できませんが。)
D言語では、人によってはfor文以上に使うことが多くなるかもしれませんね。
#04 - goto文
今回は…
goto文についてお話します。
この構文はまずほとんど使うことはないと思います。
なので軽めに。
goto文は古くはアセンブリの時代から非常に愛されてきた文です。
forやwhileなどの繰り返し文にも代用として使えますし、switch文の代用にもすることができる、非常に強力な文です(笑)。
ちなみに、なんでほとんど使わないかというと、プログラムが煩雑になりやすいからです。
あちこちにジャンプして、流れがつかみにくいプログラム、それを、スパゲッティプログラムと言います。
そんなコードを書かないように注意しましょう。
今回のミソ
- LABEL: としてラベルを定義
- ラベルの定義は";"(セミコロン)じゃなく":"(コロン)なので注意。
- goto LABEL; としてラベルにジャンプする
- gotoを使うとプログラムコードが煩雑になりやすいため、使いどころを考えなければならない
サンプルコード
import std.stdio;
int main(char[][] args)
{
goto L_LABEL5;
L_LABEL1:
writefln("L_LABEL1");
goto L_LABEL3;
L_LABEL2:
writefln("L_LABEL2");
goto L_LABEL1;
L_LABEL3:
writefln("L_LABEL3");
goto L_END;
L_LABEL4:
writefln("L_LABEL4");
goto L_LABEL2;
L_LABEL5:
writefln("L_LABEL5");
goto L_LABEL4;
L_END:
writefln("L_END");
return 0;
}
実行結果
L_LABEL5
L_LABEL4
L_LABEL2
L_LABEL1
L_LABEL3
L_END
まとめ
サンプルコードではgoto単体として使っていましたが、ふつうはif文などと組み合わせて使用します。
もし値が1ならLABEL1にジャンプする…と。このように使うのですが、これはswitchでできますし、関数なんかにまとめたほうがよっぽど読みやすいコードになります。
できる限りgoto文をなくすようにしましょう。
#summary - まとめ
第13章のミソ
- with(構造体の変数){ 処理 }
- 上の処理のところでは、構造体の変数の名前を使用しなくてもその構造体の中身にアクセスできる
- switch(式){ 分岐 } を使うと多条件分岐になる。
- 分岐には case文とdefault文を使う
- 式 が case 値: の値になった場合、そこへ飛ぶ。
- 式 が複数ある case 値: のどの値にも当てはまらなかった場合、 default: へ飛ぶ。
- 終わる場合は break を使う。
- breakしないcase文はその次のcase文もつづけて実行する。
-
switch(式)
{
case(値1):
式が値1だったときの処理;
break;
case(値2):
式が値2だったときの処理;
break;
default:
デフォルトの処理;
}
- foreach(val;list){ ... }
- valはlistの中のデータが一つずつ入る
- foreach文を使うと、breakするかすべての要素をめぐるまでループする
- valは型名などを使ってもよいが、使わなくても勝手に推測してくれる
- foreach(ref val;list){ ... } とすると、リストの要素の変更が可能
宿題
この章で紹介したサンプルコードをすべてwith,switch,foreach,for,while文を使わずに期待される動作を全く同じになるように記述してみてください。
コメント
今回の宿題はつまり、繰返しや分岐を使わないで、どのようにプログラムが流れているかを確認するためのものです。
goto文を使って再現してみるのもいいかもしれません。あまり役には立たないと思うけど。
そんなわけで、宿題できたら、あるいは予想ついたら次にいきましょう~
ページトップ /
目次 /
次へ