算術演算子には以下のものがあります。
C言語の算術演算子、論理演算子、条件演算子、比較演算子、ビット演算子、べき乗の演算子、余りの演算子、などについて説明しています。優先順位一覧もあります。
算術演算子には以下のものがあります。
演算子 | 種別 | 例 | 意味 |
---|---|---|---|
+ | 加算 | x + y | x にy を加える。 |
- | 減算 | x - y | x からy を引く。 |
* | 乗算 | x * y | x にy をかける。 |
/ | 除算 | x / y | x をy で割る。 |
% | 剰余算 | x % y | x をy で割った余りを求める。 |
整数の割り算では、小数点以下は切り捨てられます。被演算数が負の時の切り捨ての方向は機種に依存します。
+と-は同じ優先順位です。* / %も同じ優先度で、こちらのグループの方が+と-よりも優先順位が高くなります。
C言語で「余り」を求める演算子は%です。x % yはxをyで割った余りになります。この余りを求める演算子はfloatやdoubleに対しては使えません。被演算数が負の時の余りの符号は機種依存となります。
浮動小数点数に対して、余りを求めたい場合はfmod標準ライブラリ関数を使用します。文法は以下のとおりで、この関数はx/yの余りを返します。
#include <math.h>
double fmod(double x, double y);
C言語の論理演算子には以下のものがあります。
演算子 | 種別 | 例 | 意味 |
---|---|---|---|
&& | 論理積(AND) | a && b | a とb が共に真の場合「真」 |
|| | 論理和(OR) | a || b | a またはb が真の場合「真」 |
! | 否定(NOT) | !a | a が偽の場合「真」、a が真の場合「偽」 |
論理演算子を使う上で注意すべき点があります。それは、&&と||を使った場合、左側から式が評価され、その評価は全体の真、偽が決定した時点で終わる、ということです。これは、左側の式の真偽が、右側の式の実行条件になっている、ことを意味しますし、また、左側の式の真偽によって、右側の式が実行されないこともある、ということも意味します。
具体例を見てみましょう。
#include <stdio.h>
int main(int argc, char *argv[])
{
int i=0, j=0;
if (i && (j=j+1)) {
;
}
printf("%d,%d¥n",i,j);
return 0;
}
このプログラムをコンパイル、実行すると、下記のように表示されます。
0,0
iとjは0で初期化されています。if (i && (j=j+1)) {を評価するとき、iが0ですので、この時点で(i && (j=j+1))が偽と決定しj=j+1は実行されません。そのため、iとjが共に初期値の0のままで出力されます。
iの初期値を1と変えるとプログラムの実行結果は1,1となります。if (i && (j=j+1)) {を評価するとき、iが真ですので、この時点では(i && (j=j+1))の真偽が決定しません。そのためj=j+1が実行、評価され、jが1となります。
この仕様は、うっかり忘れてしまいがちですので注意しましょう。
条件演算子(じょうけんえんざんし、conditional operator)とは、条件によって異なる値を返す演算子のことです。被演算子が3つある3項演算子のひとつです。
演算子 | 種別 | 例 | 意味 |
---|---|---|---|
? : | 条件演算子 | a ? b : c | a が真ならb が実行、a が偽ならc が実行。 |
例を見てみましょう。
cnt = (cnt < 100) ? cnt + 1 : 0;
この例ではcntが100未満なら1カウントアップされ、100以上ならcntが0となります。つまり、以下のif文と同じとなります。
if (cnt < 100) {
cnt = cnt + 1;
} else {
cnt = 0;
}
比較演算子は、関係演算子とも呼ばれ、C言語には下記のものがあります。
演算子 | 一般的な読み | 例 | 意味 |
---|---|---|---|
< | 小なり | a < b | a はb より小さい |
<= | 小なりイコール | a <= b | a はb 以下 |
> | 大なり | a > b | a はb より大きい |
>= | 大なりイコール | a >= b | a はb 以上 |
== | イコール | a == b | a とb は等しい |
!= | ノットイコール | a != b | a とb は異なる |
比較の「==」と代入の「=」をうっかり間違えるケースがよくあります。気をつけましょう。また、ノットイコールは「<>」ではなく「!=」です。
ビット演算子はビット単位でデータを操作する演算子です。操作できる型は整数(char含む)のみです。
演算子 | 種別 | 例 | 意味 |
---|---|---|---|
& | ビット毎のAND | a & b | a とb のビット単位のAND |
| | ビット毎のOR | a | b | a とb のビット単位のOR |
^ | ビット毎の排他的OR | a ^ b | a とb のビット単位の排他的OR |
<< | 左シフト | a << b | a をb ビット分、左へシフト |
>> | 右シフト | a >> b | a をb ビット分、右へシフト |
~ | ビット単位の反転 | ~a | a の各ビットを反転 |
ビット毎のAND演算子&は、指定のビットをマスクするためによく使われます。例えば、x = x & 0x0Fとするとxの下位4ビット以外は0になります。
ビット毎のOR演算子|は、指定のビットをオンにするためによく使われます。例えば、x = x | 0x02とするとxの下位2ビット目が1になります。
ビット毎の排他的OR演算子^は、2つの数の対応するビットが異なる時にそのビットが1になり、同じ時にそのビットが0になります。例えば、x = 0xE7 ^ 0x7Eならxは0x99になります。
シフト演算子<<と>>は左側の被演算数を右側の被演算数のビット数分シフトさせる演算子です。例えばx << 1ならxを左へ1ビットシフトします。空になるビット、今の場合は右から1ビット目、には0が入ります。unsignedの数の右シフトでは左から0が入ります。signedの数の右シフトでは、計算機によって、左から符号桁が入ってくる場合(算術シフト)と0が入ってくる場合(論理シフト)があります。
単項演算子~を使うとビットの反転が行えます。ビット単位で1が0に、0が1になります。~はチルダと読みます。~をニョロと呼ぶ人もいます。
C言語にはべき乗(累乗)の演算子はありません。べき乗を計算するときは標準ライブラリ関数のpow()を使用します。文法は以下のとおりです。xのy乗を返します。
#include <math.h>
double pow(double x, double y);
べき乗(累乗)の演算子は^でも**でもありません。うっかり間違えないように気をつけましょう。特に^の場合、コンパイルエラーとはなりませんので注意が必要です。
1つの式の中に複数の演算子が現れた場合には、各演算子の優先順位と結合規則によって演算の順番が決まります。演算子の優先順位と結合規則をまとめた表が下記の表です。
優先順位 | 演算子 | 用法 | 名称 | 結合規則 |
---|---|---|---|---|
1 | [] | a[b] | 添字演算子 | 左から右 |
() | a(b) | 関数呼出し演算子 | 左から右 | |
. | a.b | ドット演算子 | 左から右 | |
-> | a->b | ポインタ演算子 | 左から右 | |
++ | a++ | 後置増分演算子 | 左から右 | |
-- | a-- | 後置減分演算子 | 左から右 | |
2 | ++ | ++a | 前置増分演算子 | 右から左 |
-- | --a | 前置減分演算子 | 右から左 | |
& | &a | 単項&演算子、アドレス演算子 | 右から左 | |
* | *a | 単項*演算子、間接演算子 | 右から左 | |
+ | +a | 単項+演算子 | 右から左 | |
- | -a | 単項-演算子 | 右から左 | |
~ | ~a | 補数演算子 | 右から左 | |
! | !a | 論理否定演算子 | 右から左 | |
sizeof | sizeof a | sizeof演算子 | 右から左 | |
3 | () | (a)b | キャスト演算子 | 右から左 |
4 | * | a * b | 2項*演算子、乗算演算子 | 左から右 |
/ | a / b | 除算演算子 | 左から右 | |
% | a % b | 剰余演算子 | 左から右 | |
5 | + | a + b | 2項+演算子、加算演算子 | 左から右 |
- | a - b | 2項-演算子、減算演算子 | 左から右 | |
6 | << | a << b | 左シフト演算子 | 左から右 |
>> | a >> b | 右シフト演算子 | 左から右 | |
7 | < | a < b | <演算子 | 左から右 |
<= | a <= b | <=演算子 | 左から右 | |
> | a > b | >演算子 | 左から右 | |
>= | a >= b | >=演算子 | 左から右 | |
8 | == | a == b | 等価演算子 | 左から右 |
!= | a != b | 非等価演算子 | 左から右 | |
9 | & | a & b | ビット単位のAND演算子 | 左から右 |
10 | ^ | a ^ b | ビット単位の排他OR演算子 | 左から右 |
11 | | | a | b | ビット単位のOR演算子 | 左から右 |
12 | && | a && b | 論理AND演算子 | 左から右 |
13 | || | a || b | 論理OR演算子 | 左から右 |
14 | ? : | a ? b : c | 条件演算子 | 右から左 |
15 | = | a = b | 単純代入演算子 | 右から左 |
+= | a += b | 加算代入演算子 | 右から左 | |
-= | a -= b | 減算代入演算子 | 右から左 | |
*= | a *= b | 乗算代入演算子 | 右から左 | |
/= | a /= b | 除算代入演算子 | 右から左 | |
%= | a %= b | 剰余代入演算子 | 右から左 | |
<<= | a <<= b | 左シフト代入演算子 | 右から左 | |
>>= | a >>= b | 右シフト代入演算子 | 右から左 | |
&= | a &= b | ビット単位のAND代入演算子 | 右から左 | |
^= | a ^= b | ビット単位の排他OR代入演算子 | 右から左 | |
|= | a |= b | ビット単位のOR代入演算子 | 右から左 | |
16 | , | a , b | コンマ演算子 | 左から右 |
1つの式の中に複数の演算子が現れた場合、優先順位の高いものから評価されます。優先順位が同じであった場合には、結合規則の方向に演算が行われます。例えば、a + b * cの場合は、*の優先順位が高いので、a + (b * c)と解釈されます。a + b - cの場合は、+と-は優先順位が同じですので、結合規則にしたがって(a + b) - cと解釈されます。
優先順位は、1つの式の中に複数の演算子が現れた場合に、どの演算子から評価するかを示すものであり、結合規則は優先順位が同じであった場合、左右どちらの演算子と結合して、先に評価するのかを示すものです。