制御文
if 文
if ( a == 12 ){ // もし a が12なら
:
A; // A部分を実行する
:
} else { // そうで無ければ( aが12で無ければ)
:
B; // B部分を実行する
:
}
実行する部分の命令が1行のときは大カッコ( {} )を省略してもOKです。
if (a == 12) // もし a が12なら
b = 0; // b に0を入れる
else // そうでなければ
b = 1; // b に1を入れる
また、 else は必要無ければ書く必要はありません。
if (a == 12 ) // もし、a が12なら
b = 34; // bに34を入れる
上の文は以下のように1行に書いても大丈夫です。
if ( a == 12 ) b = 34;
条件式がたくさんある場合
if (a == 12 ){ // 条件1 a が12なら
b = 12; // b に12を入れる
} else if (a == 34){ // 条件1ではなくて a が34の場合は
b = 34; // b に34を入れる
} else if (a == 56){ // 条件1でも条件2でもなくて a が56の場合は
b = 56; // b に56を入れる
} else { // 上のどの条件にも当てはまらない場合は
b = 78; // b に78を入れる
}
の様に書きます。
上の場合では、複数の条件が成立することはありませんが、中には複数の条件に当てはまる場合もありますが、その場合は条件があったらその命令を実行してこのif文からぬけます。
つまり、複数の条件があったとしても、複数の命令は実行されないという事です。
?: 関係演算子 あるいは 条件演算子
式1 ? 式2 : 式3 という書き方をします。
式が3個あるので、3項演算子といいます。
これは、式1が真なら 式2を式1に代入、そうで無ければ式3を式1に代入するというモノです。たとえば
a ==4 ? 5 : 9;
a が4の場合は a に 5 を入れる、そうでなければ aに9をいれる
これは
if (a == 4)
a = 5;
else
a = 9;
と同じです。
じゃあ、こちらの方が読みやすくていいんじゃないですか?どうでしょう。
最近はとんとみなくなりましたが、人のソースを読むときのために説明しました。
switch文
条件によって処理する事が違う場合に使います。
switch( a ){ // a に付いて
case 1: 処理1 // a==1 の場合は処理1を実行する
break; // 処理1を実行したので、switch文から抜ける
case 2: 処理2 // a==2 の場合は処理2を実行する
break; // 処理2を実行したので、switch文から抜ける
case 16: 処理3 // a==16 の場合は処理3を実行する
break; // 処理3を実行したので、switch文から抜ける
case 99: 処理4 // a==99 の場合は処理4を実行する
break; // 処理1を実行したので、switch文から抜ける
default: 処理5 // どの条件にも当てはまらない場合は 処理5を実行する
}
処理したとあとに break 文を忘れないようにしましょう。
break を忘れるとその下にある命令をどんどん実行してしまいます。
for 文
繰り返し文です。
for ( a =0; a < 67; a ++){
処理
}
という書き方です。
カッコの中は
(式1;式2;式3)
となっています。
;で区切られた式が3個あるわけですが、これは
式1 始めの条件をセットする
式2 繰り返す条件
式3 実行するたびにどうするか
for ( a =0; a < 67; a ++){
処理1
}
この例では、
始めに a に0を入れる。
a が67より小さければ処理1を実行する
a を+1する
となります。
0から、66回まで、67回処理1を実行するわけですね。
以下のような書き方も出来ます。
for(int a = 12; a != 0; a *= b){
処理1
}
日本語に翻訳すると、ここで int 型の a を定義して、12を入れる
a が0で無ければ処理1を実行する
a に a * b を入れる
もちろん、処理1の中でbを変化させてそのうちa*bが0にならなければ永遠にこのfor ループから抜け出せません。
複雑な条件を考えるときは注意しましょう。
while 文
while( a < 0){
処理1
}
a が0より小さい間、処理1を実行します。
処理1を実行したあと、また a を見て同じことを繰り返します。
a がはじめから0のとき(はじめから条件がTRUEだった場合)は処理1は一度も実行されません。
do while 文
do
処理
while( a < 100);
この文は while と似ています。
do があると、とりあえず処理1を実行します。
実行したあと、条件を見て、再び同じことをします。
この文ははじめから条件がTRUEになっていても必ず1回は処理1を実行します。
break 文
for 文、while文の途中から抜ける場合に使います。
switch 文でも使いましたね。
do
処理1
if (x == 3) break;
while(a < 100);
次の処理
とか、
for (a = 0; a < 100; a++){
処理1
if (x < b) break;
}
次の処理
の様に使います。
break があると、ループのカッコをぬけて次の処理に行きます。
continue 文
この文は、処理の頭にもどります。
while( a < 100){ ------- 1
処理1 ------- 2
if (x < 55) continue;------ 3
処理2 ------- 4
}
これは処理1を実行して x が55より小さい場合は1に戻ります。
そうで無ければ処理2を実行して1に戻ります。
for (a=0; a <34; a++){ -----1
処理1
if (x==3) continue;
処理2
}
for 文の場合は、1の a++ に戻って再びループを開始します。
goto 文
void main()
{
int a = 0;
for (int i = 0; i<100; i++){
:
:
if (i == 55) goto kaeru;
}
kaeru:
}
の様に使います。
ループの中からいきなり kaeru に飛ぶ訳です。
Cでは、これは不吉なモノとして使ってはいけないとされています。
プログラムの流れがきれる、というか、構造化になじまないとかいろいろ言われますがやはりCというか、C++では美しくないからでしょう。
古典的なプログラムを読むための知識くらいに考えて下さい。
ソフト会社によっては使用禁止のところもあるようです。
使わないようにしましょう。
プリプロセッサ命令(マクロ)
いままでソースの頭に
#include <iostream.h>
という文を書いていましたが、これがプリプロセッサ命令です。
頭に # をつけます。
#include は含めるという命令と説明しましたが、実際の動作はこうです。
iostream.h の中味(これは例なのでほんとの中味は違います)
void aaa();
void bbb();
の2行としましょう。
作ったプログラムは
#include < iostream.h>
#include <iostream.h>
void main()
{
cout << "テストです" << endl;
}
だとします。
すると、コンパイラは、これを
#include < iostream.h>
void aaa();
void bbb();
void main()
{
cout << "テストです" << endl;
}
という風に、一つのファイルに展開します。
それからコンパイルを始めるわけです。
コンパイルの前に処理する、という意味でプリプロセッサな訳です。
マクロともいいます。
マクロと言う方が古い感じがします。
これはアセンブラ時代からあるせいでしょう。
#define
これは文字マクロと呼ばれます。
#define otaku 3
というように使います。
int a;
a = otaku;
とすると、a に3が入ります。
これもプリプロセッサなのでコンパイラはコンパイル前に
a = otaku;
を
a = 3;
に入れ替えてからコンパイルを開始します。
#ifdef #ifndef #else #endif #elif
これらのマクロはセットで使います。
下の例を見てください。
#define _Win_flag 0 // _Win_flag を定義する
#ifdef _Win_flag // _Win_flag が定義されていれば
#include < windows.h > // windows.h を include する
#else // そうで無ければ
#include < unix.h> // unix.h をinclude する
#endif
一行づつ見てみると、何をやっているかわかりますね。
この例では、
#define _Win_flag 0 // _Win_flag を定義する
が定義されていると、ウインドウズのヘッダファイルがインクルードされます。
そうでない場合はユニックスのヘッダファイルをインクルードします。
これは、一つのファイルで複数のプラットフォーム(OSの事です)に対応するために使っています。
うまくすると、
<playstation2.h>
なんていうヘッダファイルをインクルード出来るようになるかもしれませんね。
#ifndif
#ifdef と同じですが、これに続くシンボルが定義されていない場合には続くコードを
実行します。
#denfine _Win_flag 0 // _Win_flag を定義する
#ifdef _Win_flag // _Win_flag が定義されていれば
#include < os2.h > // windows.h を include する
#else // そうで無ければ
#include < windows.h> // unix.h をinclude する
#endif
この例では、_Win_flag が定義されていない場合は、os2.h をインクルードする。
そうでなければウィンドウズのヘッダファイルをインクルードするということになります。
#elif
else if と同じ命令のマクロ版です。
これらのマクロは
#ifdef _unix
sti = 123;
#else
sti = 999;
#endif
の様にコンパイルするコードそのものを分離する目的で使うことも出来ます。
マニピュレータ
Cでコンソールに文字を表示するのには printf() という関数を使いました。
C++になると、ストリームという関数が用意されました。
iostream.h に宣言されています。
#include < iostream.h> と書くのは、cin cout を使えるようにするためです。
printf() を使うためには
#include < stdio.h>
と書きますね。
printf() はさまざまな書式をもっていろいろな表示が出来るようになっています。
しかし、私としてはこれは使いたくないと思っています。
どうも書式が震いというか、面倒なんですね。
cin cout を使う方が便利だと思うからです。
直感的にもわかりやすいし。
たとえば数値を表示するのに printf では16種類のデータタイプの指定が必要ですが cout は、ただ
int a;
double a;
long a;
float a;
のすべてが
cout << a
で済んでしまいます。
今後はおそらくコンソールプログラムを実用的に使うことは減ってゆくと思われるのでストリームを使用するのを推奨します。
しかしストリームにもちょっと弱点があります。
それを補うのがマニピュレータです。
いままでコンソールに出力する文字列を改行させるために
cout << "これがコンソール文字列だ\n";
のように文字列の最後に \n という文字をつけていました。
これは、エスケープシーケンスという、文字列をスクリーンに表示するための命令のようなものです。
C++では、これらのエスケープシーケンスの代わりにマニピュレータというものを使います。
下のふたつの命令は同じ結果になります。
1 cout << "これがコンソール文字列だ\n";
2 cout << "これがコンソール文字列だ" << endl;
2の命令の最後にある endl がマニピュレータです。
マニピュレータと使用例の一覧です。
マニピュレータ
|
機能
|
用途
|
使用例
|
oct
|
8進数処理 |
入出力 |
cout << oct << i; 出力
cin >> oct >> i; 入力 |
dec
|
10進数処理 |
入出力 |
cout << dec << i; 出力
cin >> dec >> i; 入力 |
hex
|
16進数処理 |
入出力 |
cout << hex << i; 出力
cin >> hex >> i; 入力 |
wa
|
空白読み飛ばし |
入力 |
cin >> wa >> i; 入力 |
flush
|
バッファのフラッシュ(書き出し) |
出力 |
cout << i << flush; 出力 |
endl
|
改行出力付きフラッシュ |
出力 |
cout << I << endl; 出力 |
ends
|
"\0"を追加してフラッシュ |
出力 |
cout << i << ends; 出力 |
|