Version 6.10
二項演算子
「今回は前回に引き続き、演算子について見ていきましょう」
『今回は二項演算子、ようするに右と左、ふたつ使う演算子だよね』
「そう、この演算子が一番多いかな。 MSDN の【2 項演算子】−【2 項演算
子】を見て」
『ホントだ、いっぱいあるね』
「多いからとっとと行きましょう。まず一番大事な = 」
『変数に値入れるのだね。だいにゅうって言うんだっけ』
「そう、代入。これは大丈夫だね。次は四則演算の + - * / % 」
『足す引く掛ける割る……最後のは?』
「割り算の余り。 5 % 3 なら」
『余り 2 ね。これ何に使うの?』
「実は色々使えるんだよね。たとえば for ループで」
void CDebugDlg::OnButton1()
{
for( int iF1 = 1; iF1 <= 30; iF1++ )
{
if( ( iF1 % 5 ) == 0 )
{
TRACE( "%d ", iF1 );
}
}
// 5 10 15 20 25 30
}
『おー、5回ずつ、ってこうすればいいんだ』
「他にもあるけど、それはまたおいおい。で、こういった四則演算に代入の
機能が付いたのが、 *= += -= /= %= 」
『そうそう、 + とかの結果は変数に描き込まれないからわざわざ = で代入
しなきゃいけない。それをしなくていいのが += とかだよね』
「そう、 A += B は A = A + B と同じ。ここでちょっと一息」
『ふぅ』
「さて、ここで昔を思い出して。四則演算教えた Ver 2.4 ( No.015 ) で、
優先順位っていうのについて教えたでしょ」
『 * や / の方が + や - よりも先に計算される、ってヤツでしょ』
「その辺、も少ししっかり教えとくね。 MSDN の【結合規則】−【優先順位
と評価順序】ってページ表示して」
『ん、演算子の表がある』
「この表の中で、上の方が優先順位が高くて、下の方が低くなってます」
『 + とかは上から2番目、 = や += なんかは下から2番目』
「この優先順位があるから、 A = A + B は A + B が先に計算されるんで
す」
『あ、そっか、もし + よりも = の方が高かったら、 A = A が先になっ
て、そのあと + なんだ』
「そゆこと。ただ、 ( ) で囲んだらそっちが先に実行されるからね」
『ってことは、 ( A = A ) + B ってしたら今言ったようなことになっちゃ
うってことね〜』
「優先順位は、式の意味そのものに関わってくるから大事。もうひとつ、
結合規則っていうのがあるんだけど」
『左から右、右から左って書いてあるね』
「これは、右と左、どっちのオペランドが先に処理されるか。たとえば」
int FuncL()
{
TRACE( "FuncL\n" );
return 0;
}
int FuncR()
{
TRACE( "FuncR\n" );
return 0;
}
void CDebugDlg::OnButton1()
{
int i = FuncL() - FuncR();
// FuncL
// FuncR
}
『あー、 + は〈右から左〉って書いてあるから FuncR() が先に実行されて
ねーっ!! なんで?』
「同じページの真ん中へんに書いてあるけど、基本的にこれは不定。開発環
境によってまちまちなんだよねー」
『……じゃーどうすればいいの?』
「 ( ) とか使って、そういうの関係なく順番を決めてけばいいだけ。だか
ら結合規則は忘れていーよ」
『なんかてきとー』
「ってゆーか、優先順位も忘れていいんだけどね」
『え、そうなの?』
「そ。それはまた今度。次はビット操作、 & | ^ << >> 」
『これは全部知ってる』
「 Ver 4.05 ( No.055 ) とかでやったね」
『あ、嘘、 ^ って知らない』
「そういえば」
『ビット操作するのだよね。なんか ~ に似てるけど』
「違うのだからね。 ^ は〈排他的 OR 〉って言って、……えっと、 & と |
の機能を言ってみて」
『 & は両方とも 1 のとき 1 、 | はどっちかが 1 のとき 1 になる、ね』
「 ^ は 1 と 0 、または 0 と 1 、つまりビットが違う時に 1 。 1 と 1
か 0 と 0 、つまりビットが同じ時は 0 」
『?』
「つまり」
void CDebugDlg::OnButton1()
{
TRACE( "%X\n", 0x05 ^ 0x03 ); // 6
// 0101
// ^ 0011 は
// 0110 に。
}
『違うとき 1 、同じとき 0 、だからこうなるんだ』
「実は、これを使うと前回紹介した ~ を使う〈ビットフラグを取り除く方
法〉が実現できるんです」
『え、こっちでも?』
「上の例で見てみて。 0x03 で 0 になってるビットは、 0x05 のときのま
まになってるでしょ」
『そだね。ってことは、変えたくないビットは 0 にしとけばいいんだ』
「で、変えたいビットは 1 にすればいいわけ。そのビットが 1 なら 0 に
なるから」
『そうすればビットフラグを取り除けるってわけね。あれ? でもこれ、
ビットが 0 だったら 1 になっちゃうね』
「そだね。前回の ~ 使ったのはそういうことないから、そういう意味じゃ
~ の方を使った方がいいかも」
『演算子の使い道って、結構少ないのね……』
「さて、これらのビット操作系も、四則演算のときみたく代入バージョンの
&= |= ^= <<= >>= があったりします」
『あ、前回の ~ は & も使わなきゃいけなかったけど、今回のなら ~= ひと
つでできるね』
「そーゆー、横着優先で考えちゃダメ」
『うー』
「んじゃ次、 if の中とかで使う比較系。 == != < <= > >= 」
『だいぶ前だけど、全部やったよね』
「 Ver 2.6 ( No.017 ) 、ほんとにだいぶ前だね……。で、この比較系と一
緒によく使われるのが && と || 」
『あれ? これってまだちゃんと教わってないかも』
「じゃ、ここでしっかり教えときましょう。まずは & と | のちゃんとした
呼び方から。このふたつは〈ビット AND 〉と〈ビット OR 〉って言います」
『ビットエンドとビットオア、ね』
「 AND は〈〜と〜〉、つまり両方ともって意味」
『 & は両方とも 1 のとき 1 、それが〈両方とも〉ってことね』
「 OR は〈〜か〜〉、つまりどっちかって意味」
『 | はどっちかが 1 のとき 1 、ね』
「で、このふたつは各ビットについてのだったけど、 && は || は整数値全
体に対して使います。名付けて〈論理 AND 〉と〈論理 OR 〉」
『ろんりエンドとろんりオアね。整数値全体ってどういうこと?』
「その名の通り。整数として、両方とも 0 以外の時、 0 以外になるのが
&& 演算子」
TRACE
( "%d, %d, %d, %d\n"
, 0 && 0, 0 && 1, 1 && 0, 1 && 1 );
// 0, 0, 0, 1
『あーそっか、普通に数字で判断するんだ。で、 1 と 1 の時だけ 1 ね』
「別に 1 って決まってないからね」
『 0 以外、ってヤツ?』
「そ。〈 0 以外〉が 1 とは決まってなくて、 開発環境の中には -1 だっ
たりするのもあるからね。 VC は 1 ってだけのこと」
『っつーか〈 0 以外〉って言葉自体分かりにくいし』
「ま、 if や while が〈 0 以外の時に実行される〉んだから、 0 以外は
〈当たり〉とか置き換えちゃえばいいでしょ」
『当たり、ね。あとさ、この 1 とか 0 って、変数にもできるんだよね』
「もちろん。まー、実際にはこういう使い方はあんましないかも。普通の使
い方の前に、 || の例も見といて」
TRACE
( "%d, %d, %d, %d\n"
, 0 || 0, 0 || 1, 1 || 0, 1 || 1 );
// 0, 1, 1, 1
『 || はどっちかが 1 なら 1 ね。この辺は & や | と同じだから分かり
やすいかも』
「で、これは if の中で使います。
int i = 5;
if( ( 0 <= i ) && ( i <= 10 ) )
{
TRACE( "Hit!!\n" );
}
// Hit!!
『えーっと、左っかわの 0 <= i は、 i が 0 以上なら当たり、右っかわの
i <= 10 は、 i が 10 以下なら当たり。で、 && は両方とも当たりなら当
たり。ん? よーするに i が 0 以上で 10 以下ならいいってこと?』
「そゆこと。逆に考えると〈 i が 0 から 10 の間か〉を if で調べたいと
きにはこうすればいいってこと」
『例の〈使い道から〉ってのね。 || の方は?』
「たとえばこれの逆、 0 未満か 10 より大きいとき、とか」
int i = 15;
if( ( i < 0 ) || ( 10 < i ) )
{
TRACE( "Hit!!\n" );
}
// Hit!!
『そっか、これは && じゃダメなんだ。 0 未満で 10 より大きい、なんて
あり得ないもんね』
「他にもいっぱい使い道があるんだけど、それはまたおいおい、ね」
『で、他の演算子は?』
「それは次回に続く!」
/*
Preview Next Story!
*/
『結局、使い道知らないとどうしようもない?』
「演算子は自由度の高い道具だから、使い方を知らないとね」
『機能そのものは簡単なのに』
「そういうのをどれだけ知ってるか、もスキルのうちかも」
『ふ〜ん』
「というわけで次回」
< Version 6.11 三項演算子 >
『につづく!』
「演算子だけ教える、って今までしてこなかったのはそういう理由」
『ホントかな〜』