C言語では次の種類の演算が行える.
これらの演算子には,優先順位が定められている.
それぞれの演算を行う前に,次の型変換が自動的に行われることに注意.
データ型で説明したように,charなど文字型も 計算に使用できるが,サイズが小さい型で計算するとオーバーフローなどの問題 を生じるため,C言語ではあらかじめ次の変換が自動的に行われてから計算され る.
char → int short → int unsigned char → unsigned int unsigned short → unsigned int float → double
つまり,charであればまずそのデータがint型に拡張されてから計算されるた め,計算結果が-128から127の範囲を超えてしまっても,結果は正しく計算され ることになる.(ただし,せっかくの結果をchar型の変数に代入すると,-128から127 の範囲になるように切り捨てられてしまうので注意.)
C言語での計算式は,次の演算子を用いて行う.
* | かけ算 |
/ | 割り算 |
% | 剰余(割り算のあまり) |
+ | 足し算 |
- | 引き算 |
C言語では普通に四則演算ができる.演算の対象は,整数でも実数でも良い. しかし演算の結果は,整数の計算の場合には整数,実数の計算の場合には実数と になる.例えば,整数で7/5を実行すると結果は1になるが,7.0/5.0を実行する と,1.4になる.
もしも,整数と実数の計算を行う場合には,計算は実数で行われる.より詳 しく説明すると,C言語では演算対象の型が異なるときには,次のルールによっ て計算するときの型を決定している.
どちらか(両方)がdouble → doubleで計算(計算結果もdouble) そうでないとき どちらか(両方)がunsigned long → unsigned long そうでないとき どちらかがlongでもう一方がunsigned int → unsigned long そうでないとき どちらか(両方)がlong → long そうでないとき どちらか(両方)がunsigned int → unsigned int そうでないとき 両方ともintのはずだから → int
この型の計算は自動で行われるので,プログラマはそれを頭に入れて演算を 記述すること.
C言語ではそれに加えて割り算のあまりを計算する「%」も用意されている. 例えば 「12%7」は「5」になる.剰余は四則演算と異なり,整数型(int, char, long,さらにそれぞれのunsigned型))が演算対象で,実数を計算することはでき ない.(計算する際には上記の型の変換が行われる).
<< | 左シフト |
>> | 右シフト |
シフト演算は,アセンブリ言語における二進数のシフト演算と同じものであ る.例えば次のように書くと,2ビットの左シフトを行う.
unsigned char x,y; x = 0x01; y = x << 2; //xを2ビット左シフトして,yに格納
この例ではyに4が格納される.
0x01を二進数にすると 0000000000000001B ( unsigned char型の変数だが,計算時にはunsigned int の16bitに変換される) 2ビット左シフトすると0000000000000100B,これは「4」 (<-2ビット左へずれた)
シフト演算も剰余と同様に整数しか演算対象に指定できない.
シフト演算には,符号付きの算術シフトと符号無し の論理シフトがある.シフト演算子は,演算対象のど ちらか一方がunsigned 型である場合,論理シフト,両方とも符号付きの型の 場合に算術シフトを行う.
アセンブリ言語でのように,論理演算(NOT,AND,XOR,OR)を書くことができる. 最初のNOTは単項演算で,残りは二項演算である.
演算子 | 種類 | 意味 | ビットごとの操作内容 |
---|---|---|---|
~ | NOT | 論理否定(ビット反転) | 1と0を逆にする(反転) |
& | AND | 論理積 | どちらかが0なら0 |
| | OR | 論理和 | どちらかが1なら1 |
^ | XOR | 排他的論理和 | 両方同じなら0,違っていたら1 |
単項演算とは,対象がひとつだけの演算で例えばNOTは次のように書く.
unsigned char x,y; x = 0xAA; y = ~x; //xをビット反転した結果を,yに代入
C言語では真(true)は数値「1」,偽(false)は数値「0」で示される.この動 作を説明する.
0xAAを二進数にすると 0000000010101010B ( unsigned char型の変数だが,計算時にはunsigned int の16bitに変換される) ビット反転すると 1111111101010101B,これは「0xFF55」yはunsigned char型の8bitなので上位8bitは無視されて 01010101B つまり「0x55」がyに代入
残りの演算子は二項演算である.二項演算は,四則演算と同様に対象が二つ ある演算で,例えばANDは次のように書く.
unsigned char x,y; x = 0xA5; y = x & 6;
0xA5を二進数にすると 0000000010100101B ( unsigned char型の変数だが,計算時にはunsigned int の16bitに変換される) 6を二進数にすると 0000000000000110B ANDを取って 0000000000000100B これは「4」
++ | 増分(1増やす)演算 |
-- | 減分(1減らす)演算 |
変数の内容を1ずつ増減させる単項演算子「++」と「--」が用意されている.単項演算は先に説明した通り, 対象が一つだけの演算で,例えば次のように書く.
x++; または ++x;
これで変数xに1が加えられる.つまり,これは次と等価である.
x = x+1;
「--」ならば逆に1減らされることになる.
変数の前におくものを前置演算,後におくものを後置演算と呼ぶ.その違い は,式の評価と演算の順番が異なることである.演算結果を別の変数に代入する ときなどに影響がある.例えば.
x = 0; y = x++;
このプログラムは次のプログラムと等価であり,結局yには0が代入される.
x = 0; y = x; x = x+1;
逆に前置演算の場合は
x = 0; y = ++x;
次の例と等価であり,yには1が格納される.
x = 0; x = x+1; y = x;
変数に値を代入するための演算子として次のものが用意されている.
= | 左辺に右辺の結果を代入する |
+= | 左辺に左辺+右辺の結果を代入する |
-= | 左辺に左辺-右辺の結果を代入する |
*= | 左辺に左辺*右辺の結果を代入する |
/= | 左辺に左辺/右辺の結果を代入する |
%= | 左辺に左辺%右辺の結果を代入する |
<<= | 左辺に左辺<<右辺の結果を代入する |
>>= | 左辺に左辺>>右辺の結果を代入する |
&= | 左辺に左辺&右辺の結果を代入する |
|= | 左辺に左辺|右辺の結果を代入する |
^= | 左辺に左辺^右辺の結果を代入する |
例えば次のように書く.
x += y;
これは,次の式と等価である.
x = x+y;
if文で使用する比較演算や条件演算は,次の関 係演算子を使用する.
== | 等しい |
!= | 等しくない |
< | より小さい |
> | より大きい |
<= | 以下 |
>= | 以上 |
例えば次のようにして利用し,xが100と等しいかどうか判定させることがで きる.
if( x == 100) { 条件が成立したとき }
これら関係演算子を用いた条件式を,次の論理演算で複数結合することもで きる.
! | 条件のNOT「ではない」 |
&& | 条件と条件をAND(「かつ」) |
|| | 条件と条件のOR(「または」) |
例えば次のように使うと,条件が成り立たないことを調べることができる
if( !(x == 100) ) { xが100でなかったとき }
例えば次のように使うと,二つの条件式が両方成り立つかどうか調べること ができる.
if( x == 100 && y = 200 ) { 条件がふたつとも成立したとき }
次のように使うと,二つの条件式がどちらか一つ(または両方でもよいが)成り立つかどうか調べることができる.
if( x == 100 || y = 200 ) { 条件がどちらか成立したとき }
ここまで説明してきた演算子には優先順位があり,並べて書いたときの計算 順序が決められている.
優先度高い | x++, x-- |
++x, --x | |
++x, --x | |
~ | |
! | |
- | |
*, /, % | |
+, - | |
<<,>> | |
<, >, <=, >= | |
==, != | |
& | |
^ | |
| | |
&& | |
|| | |
? : | |
=, +=, -=, *=, /=, %= | |
優先度低い | <<=, >>=, &=, ^=, |= |
この演算子の優先順位を変えた計算を行う場合には,数学における計算式と 同様に括弧()を使用できる.