連載
» 2002年10月09日 00時00分 公開

連載 改訂版 C#入門:第8章 式と演算子 (2/3)

[川俣晶(http://www.autumn.org/),(株)ピーデー(http://www.piedey.co.jp/)]

8-2 四則演算子(+、-、*、/)

 基本的に、四則演算は、常識のとおりに機能する。「+」は足し算、「-」は引き算、「*」は掛け算、「/」は割り算である。ただし、Visual Basicプログラマーはいくつか注意が必要である。これらの演算子は、そのままではオーバーフローをチェックしない。そのため、値が桁あふれを起こした場合、単純にあふれた桁を捨てた値になる。最小値と最大値は、データ型によって異なり、また、符号付きと符号なしでも異なる。ベテラン・プログラマーは、桁あふれ分が消えてしまうことを前提にプログラムを書くこともあるが、完全にオーバーフロー時の動作を把握できない場合は、「オーバーフロー、アンダーフローしないようにプログラムを書く」ということを心掛けよう。そうしなければ、出力結果の3〜5行目、7〜8行目、10〜11行目のような、一見でたらめな結果を得ることになる。

  3: 2147483647+1  =   -2147483648
  4: 2147483647u+1u  =   2147483648
  5: 4294967295u+1u  =   0
  6: 3-2 =   1
  7: -2147483648-1   =   2147483647
  8: 0u-1u   =   4294967295
  9: 3*2 =   6
 10: 2147483647*2  =   -2
 11: 2147483647u*2u  =   4294967294

 割り算には別の注意がある。整数と整数の割り算は整数になり、端数が出ても小数形式に変換されたりしない。小数の割り算を行う場合は、浮動小数点数と浮動小数点数の割り算として行わなければならない。12〜13行目が整数の割り算で、14行目が浮動小数点数の割り算である。

 12: 6/3 =   2
 13: 6/5 =   1
 14: 6.0/5.0 =   1.2

8-3 剰余演算子(%)

 「%」は割り算を行ったときの余りを得る演算子である。出力結果の15行目は6割る3の余りが0であることを示す。16行目は6割る5の余りが1であることを示す。剰余演算子は整数で使う。

 15: 6%3 =   0
 16: 6%5 =   1

8-4 比較演算子(<、>、<=、>=、==、!=)

 数値の大小と一致を比較する演算子である。演算の結果は、条件が成立すればtrue、成立しなければfalseという値になる。Visual Basicプログラマーは、一見似て非なる書式に注意しなければならない。Visual Basicでは一致は「=」だが、C#では「==」と2文字のイコール記号を記述する。不一致は、「<>」ではなく、「!=」と書く。また、「=>」や「=<」はVisual Basicでは大丈夫だが、C#では使えない。

 17: 1<2 =   True
 18: 2<1 =   False
 19: 3<3 =   False
 20: 1>2 =   False
 21: 2>1 =   True
 22: 3>3 =   False
 23: 1<=2  =   True
 24: 2<=1  =   False
 25: 3<=3  =   True
 26: 1>=2  =   False
 27: 2>=1  =   True
 28: 3>=3  =   True
 29: 1==2  =   False
 30: 2==1  =   False
 31: 3==3  =   True
 32: 1!=2  =   True
 33: 2!=1  =   True
 34: 3!=3  =   False

8-5 is演算子(is)

 「is」は、データの型を判定する。数値計算を行うほかの演算子とは少々性格が異なる。「is」の手前には任意の値を書き、後ろにはデータ型の名前を書く。もちろん、クラス名もOKである。出力結果の35〜36行目を見ると分かるが、整数の1はint型なので、「1 is int」は成立する。成立した場合はtrueの値になる。しかし、1.0は実数表記なので、整数の一種であるint型ではありえない。従って、「1.0 is int」はfalseという値になる。

 35: 1 is int  =   True
 36: 1.0 is int  =   False

8-6 論理演算子(&、^、|)

 「&」はAND演算を、「^」はXOR演算を、「|」はOR演算を行う。出力結果の37〜45行目は、trueとfalseを相手にそれぞれの演算子を適用した場合を示す。AND、XOR、ORの演算子の意味を知っていれば、結果は歴然だろう。分かりにくいのは61〜63行目で、数値を相手にこれらの演算子を使った場合だ。これらは数値を構成するビットごとに論理演算を適用することになる。ビット表現を理解しているプログラマーにのみ意味がある使い方だろう。

 37: false&false =   False
 38: true&false  =   False
 39: true&true   =   True
 40: false^false =   False
 41: true^false  =   True
 42: true^true   =   False
 43: false|false =   False
 44: true|false  =   True
 45: true|true   =   True

 

 61: 1&3 =   1
 62: 1^3 =   2
 63: 1|3 =   3

8-7 条件演算子(…?…:…)

 この演算子は3つの値を持ち、それらを「?」記号と「:」記号で分離する。「式1?式2:式3」という順番に書き、式1の結果次第で、式2と式3のどちらを解釈するかを決める。プログラミング言語ふうに書けば、「if( 式1 ) 式2 else 式3」という感じだ。そして、この演算子全体が結果として得る値は、式2か式3の中で評価された値ということになる。出力結果の46〜47行目が実際に実行した場合を示す。ここでは式1として、trueやfalseを書いているが、実際には、実行時に値が変化するような式を書く。

 46: false ? 1 : 2   =   2
 47: true ? 1 : 2  =   1

8-8 シフト演算子(<<、>>)

 シフト演算子はビットシフトを行う。「<<」は左シフト、「>>」は右シフトを示し、演算子の後ろに書く値がシフトするビット数を示す。昔は、2のべき乗数の掛け算と割り算をシフトで行うというテクニックがあったが、その程度のことなら、現在ではコンパイラの最適化機能が自動的にやってくれるので意識する必要性はほとんどないだろう。ビット表現を理解するプログラマーだけがシフト演算子を使うべきであり、それ以外のプログラマーは手を出さないほうがよいだろう。

 53: 256>>1  =   128
 54: 256<<1  =   512
 55: 2147483647>>1   =   1073741823
 56: 2147483647<<1   =   -2
 57: 2147483647u>>1  =   1073741823
 58: 2147483647u<<1  =   4294967294
 59: -2147483648>>1  =   -1073741824
 60: -2147483648<<1  =   0

8-9 単項演算子(+、-、!、~)

 単項演算子は値の手前に付ける演算子である。「+」は値の符号を変えないという機能を持つ(つまり何もしない)。「-」は値の符号を反転させる。「!」はtrueとfalseを逆転させる(not演算)。「~」は「!」と似ているが、ビット単位で数値を反転させる(1の補数を取る)。これらは、2項演算子、つまり前後に値が付く使い方をした場合と機能が異なることに注意が必要である。例えば、「x-y」は2項演算子として「-」を使っており、「-x」は単項演算子として「-」を使っている。

 48: +(2+3)  =   5
 49: -(2+3)  =   -5
 50: !true   =   False
 51: !false  =   True

 

 64: ~1  =   -2
 65: ~1u =   4294967294
 66: ~-1 =   0

8-10 インクリメント/デクリメント演算子(++、--)

 変数の前後に「++」あるいは「--」という演算子を付けることができる。「++」は変数の値に1を加え変数に戻す。「--」は変数の値から1を引き変数に戻す。出力結果の68〜71行目を見ると分かるだろう。68行目で0にセットされた変数xの値が、「x++」を表示するごとに増えていく。変数xの値が変わるのは、++演算子の効力によるものだ。同じように76〜79行目を見れば、「--」の働きで値が減っていく様子が分かると思う。

 68: set x=0
 69: ++x =   1
 70: ++x =   2
 71: ++x =   3
 72: set x=0
 73: x++ =   0
 74: x++ =   1
 75: x++ =   2
 76: set x=0
 77: --x =   -1
 78: --x =   -2
 79: --x =   -3
 80: set x=0
 81: x-- =   0
 82: x-- =   -1
 83: x-- =   -2

 さてここで問題なのは、「++」や「--」を変数の前に書くか後ろに書くかである。前と後ろでは結果が異なる。68〜71行目と72〜75行目の違いは、「++」をxの手前に書いたか後ろに書いたかの違いだけによるものである。しかし、結果としてはまったく異なっている。「++」を手前に書くと、変数xの値を利用する前に1足される、という意味になる。一方、「++」を後に書くと、変数xの値を利用した後で1が足される、という意味になる。つまり、「出力される前か後か」という相違になる。

 「++」と「--」は単独で使われることがある。つまり、「x++」とだけ書いて、その値をまったく利用しないというやり方だ。しかし、変数の中身は書き換えられるので、変数に1を足す(あるいは引く)ときには、「x = x + 1;」よりも「x++;」のほうが簡潔なため、よく用いられる。

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。