#pragma twice

KAB-studio > プログラミング > #pragma twice > 112 Version 6.12 演算子を気に掛ける!

#pragma twice 112 Version 6.12 演算子を気に掛ける!

前のページへ 表紙・目次へ 次のページへ

 Version 6.12
演算子を気に掛ける!

さて今回から、演算子関係でバグの出やすい部分や見つけ方とかを具体的
に紹介していきます
バグの出やすいとこってあるんだ
あるよー。まず重要なのは、基本型に演算子を使うって事は、関数を呼ぶ
ことじゃないってこと
何言ってんの、当たり前じゃん
まぁそれはそうなんだけど、その当たり前の事にいろんな問題があるんで
す。たとえば、書き間違い

void CDebugDlg::OnButton1() 
{
    int i = 0;
    if( i = 0 )
    {
        TRACE( "Hit!\n" );
    }
}

あ、これすんごく分かりやすいね……
え、何が?
って、気付かないの?
え”……………………あ! if( i == 0 ) じゃないの!?
そうです。これだとどうなると思う?
え? んー、普通 if の中で = なんて使わないし……
 i = 0 すると i に置き換わるから、その i が if に掛けられる、つま
り if( i ) と同じ事になるから
 i は 0 だから、 if の中に入らない!
そゆこと。で、重要なのは、 = が1個か2個かでここまで変わるってこ
と。メンバ関数ならそういうことないでしょ
そりゃ、関数の名前違っちゃうことになるんだからそうだね
演算子はシンプルだから、その分ちょっとした間違いが大きな問題になり
かねないから。それに、関数と違ってブレークポイントを付けられないで
しょ
そっか、関数が呼ばれるんなら、関数の中にブレークポイントを付けとけ
ば呼ばれるときにチェックできるんだね
これは変数にアクセスする時すべてに言えることなんだけど、関数呼び出
しと違って〈感知できない〉から、チェックが難しいんだよね
だから、色々気を付けなきゃいけないってことね
そういうこと。まずは、演算子そのものが結構危険なものだって認識を持
つことが大事かな
はーい
そしたら、どういう部分について気を付けて、どういうことをすればいい
のか見ていきます。まず今の例みたいな、 if や while の場合
 = と == ね。でも気を付けるしかないでしょ?
そうでもないよ。有名な方法でこういうのがあります

void CDebugDlg::OnButton1() 
{
    int i = 0;
    if( 0 = i )
    {
        TRACE( "Hit!\n" );
    }
}

あ、 if の中身、左右逆だ!
 == なら普通に比較するから問題なし。 = だと定数値に代入しようとす
るから
コンパイルエラーになるわけね、なるほど
ただ、僕はあまり使ってないけど
え、そなの?
だって見にくいし
見にくい?
変数が左にある方が読みやすいと思うから。この手の問題は、読みやすさ
が下がれば下がるほど見つけにくくなるから、僕としては、ね
なんか微妙なところ……
書き間違い問題には & と && や | と || とかあったりするから、そう考
えると見やすさ重視かな
こういうの違ってても、コンパイルエラーになんないんだね……
あとは、 if の話に戻ると、 == を使わないで直接 if に掛けるとかって
方法もあるかな

void CDebugDlg::OnButton1() 
{
    int i = 0;
    if( i )
    {
        TRACE( "Hit!\n" );
    }
}

でもま、今読みやすさが重要だって言ったけど、この if の使い方も、
 0 か 0 以外かって、結構混乱しやすいと思うんだよね
つまり、 i がどうだったらどうするのか、とかだよね。これって頭こん
がらがるよねー
他にも < か > かとか
そうそう、〈5以下か10以上〉とか、この前 || 使った方法教えても
らったけど、自分でやってみるとすんごくこんがらがる!
僕は数直線を想像するようにしてます
数直線?
定規の目盛りみたいなの。たとえばこんな感じ

void CDebugDlg::OnButton1() 
{
    int i = 13;
    if( ( i <= 5 ) || ( 10 <= i ) )
    {
        TRACE( "Hit!\n" );
    }
    // Hit!
}

この if の中身、 5 >= i とか i >= 10 とかしても動くでしょ
そだよね。でもこう書いた理由があるってことだよね
そう。たとえば定規で

      ++++++++++++++++++++++++++++++++++++
           -10   -5    0    5    10                  

って右側が大きい数になるように定規を置いたとき、この例で当たるのの
範囲は

      |||||||||||||||||||||||     ||||||||
      ++++++++++++++++++++++++++++++++++++
           -10   -5    0    5    10                  

の | がある範囲が当たりだよね。 i <= 5 || 10 <= i は、その通りに並
べてるわけ
 5 >= i や i >= 10 だと確かにこの図と違ってきちゃうね
 5 >= i || 10 <= i だと
書けない……
まー 5 >= i || i >= 10 でもいいけど、数学だと右に大きな数が来るこ
とが多いから
グラフなんかも左から右って多いしね。あとさ、この数直線って、結構分
かりやすいかも
そだね、それをそのままプログラムに置き換えると、僕が書いたようにな
るかな
実際に、書けるかな……
大丈夫だよ。 > や >= は使わない、って憶えとけば
そっか、右の方が大きな数字になるから > は >= は絶対使わないんだ
それさえ憶えてれば大丈夫でしょ
あ、あと、たとえば for で5周させたいとき……

void CDebugDlg::OnButton1() 
{
    for( int iF1 = 0; iF1 < 5; iF1++ )
    {
        TRACE( "%d ", iF1 );
    }
    // 0 1 2 3 4 
}

これは iF1 < 5 だけど、 iF1 <= 4 でも iF1 != 5 でも5周するで
しょ。どれ使うのがいいの?
これは難しいかなー。まず、〈5周〉ってことが分かりやすいように、
 iF1 <= 4 を使わないことが多いかな
 5 って数字が書いてあった方が分かりやすいってことね
 iF1 < 5 か iF1 != 5 は難しいところかな。 iF1 < 5 だと〈 5 未満の
間〉、 iF1 != 5 だと〈 5 にたどり着いてない間〉って意味になるから、
その意味に合った方を選ぶのがいいかなー
意味?
そう、これ大事。〈意味〉、英語で〈セマンティクス〉って言うんだけ
ど、プログラムって、字面の奥に隠された〈意味〉が存在するんだよね
普通の言葉で言うと、〈アリガト〉が感謝なのか皮肉なのか、って違いみ
たいな?
そこまでは細かくないけど、それに近い感じ。 < と != 、機能的には同
じでも意味が違ってくるし、それがプログラムの読みやすさに大きく関わっ
てくるから
そうなんだね。 for だと……結局どっちがいいってわかんないね
まーね。僕が < の方を使う理由は、万が一 iF1 が ストップさせる数字
を飛び越えちゃった時でも止まるようにしたいから
そっか、 != だと iF1 が 4 の次 6 になったら無限ループしちゃうん

滅多にないけど、ループの中でうっかり iF1 に足してたりすると
なんかありそう……。あとさ、こういうのはどう?

void CDebugDlg::OnButton1() 
{
    for( int iF1 = 1; iF1 <= 5; iF1++ )
    {
        TRACE( "%d ", iF1 );
    }
    // 1 2 3 4 5 
}

こんな感じに 1 からってのはどう? 見やすさは一番じゃないかなーと
思うんだけど
5周ループって使い道だけならいいけど、 iF1 を配列とかに使えない
よ?
そういえば。これも 1 から始まっててさっきのと結果違うし
配列を使うか使わないかで使い分けると混乱すると思うから、僕は 0 か
らって方を勧めるかな。でもこっちの方が分かりやすいってこともあるから
その辺は臨機応変
臨機応変って言ったらなんでもそうなっちゃうじゃん
ま、そうだけどね。残りは次回!

/*
    Preview Next Story!
*/
なんだかんだ言って……
ん?
水希ちゃんのプログラムってよく考えられてるってゆーか
四六時中プログラムのことばっか考えてると、ね
それもちょっと……
だから、火美ちゃんは聞いて憶えて考えて選んで使えばいいわけ
……いーの?それで?
というわけで次回
< Version 6.13 手抜きをするな! >
につづく!
ノウハウを教えていかなきゃ、いいプログラマー増えないでしょ
なんかもったいないなー
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。