式と演算子

C 言語の式 (expression) は、名前 (変数名、関数名)、定数リテラル (整数小数文字文字列)、値リスト、またはそれらを演算子 (operator) で結合したものです。
a = 3 // 二項演算子「=」を使った代入式
a += 3 // 二項演算子「+=」を使った加算式
a = b + c // a = ... と b + c の 2 つの二項演算が入れ子になった式
a < b // 比較式
a && b // 論理式

次の表は、すべての演算子の一覧です。

演算子 種類優先
順位
結合評価対象説明
(args...) 右単項 1 (N/A) 関数ポインタ 関数
[n] 右単項 1 (N/A) ポインタ/配列 配列
. 二項 1 (N/A) 左:構造体
右項:メンバ名
構造体メンバの参照
-> 二項 1 (N/A) 左:構造体
右項:メンバ名
構造体へのポインタからメンバへの参照
var++ var-- 右単項 1 (N/A) 整数、ポインタ 後置インクリメント、後置デクリメント
- 左単項 2 (N/A) 整数、小数 マイナス化
! ~ 左単項 2 (N/A) 整数 論理否定、ビット反転
* 左単項 2 (N/A) ポインタ/配列 ポイント
& 左単項 2 (N/A) 変数 アドレス
++var --var 左単項 2 (N/A) 整数、小数
ポインタ
前置インクリメント、前置デクリメント
(type) 左単項 2 (N/A) 任意 キャスト
sizeof 左単項 3 (N/A) 変数、文字列 変数または型のサイズの取得
* / 二項 4 (←) 整数、小数 乗算、除算
% 二項 4 (←) 整数 剰余
+ - 二項 5 (←) 整数、小数
ポインタ/配列
加算、減算
<< >> 二項 6 (←) 整数 左シフト、右シフト
< <= > >= 二項 7 (←) 整数、小数
ポインタ/配列
未満、以下、より大きい、以上
== != 二項 8 (←) 整数、小数
ポインタ/配列
等しい、等しくない
& 二項 9 (←) 整数 ビットごとの論理積 (AND)
^ 二項 10 (←) 整数 ビットごとの排他的論理和 (XOR)
| 二項 11 (←) 整数 ビットごとの論理和 (OR)
&& 二項 12 整数 論理積 (AND)
|| 二項 13 整数 論理和 (OR)
e1 ? e2 : e3 三項 14 左:整数
中,右:任意
三項演算 (条件演算)
= 二項 15 (←) 左:変数
右:任意
代入
+= -= 二項 15 (←) 左:変数
右:整数、小数、
ポインタ
自己演算
*= /= 二項 15 (←) 左:変数
右:整数、小数
自己演算
%=
<<= >>=
&= ^= |=
二項 15 (←) 左:変数
右:整数
自己演算
, 二項 16 任意 順次演算 (カンマ演算子)

種類
引数の取り方を示します。次のいずれかの形式です。

arg は引数、op は演算子を示します。

優先順位
演算子の優先順位 (結合力の強さ) を示します。1 が最高です。たとえば * の優先順位は + より高いので、1+2*3 では 2*3 が先に評価されます。

結合の優先順位は ( ) を使って明示的に変更できます。たとえば (1+2)*3 では 1+2 が先に評価されます。( ) および [ ] の中身は最優先で結合します。

結合
オペランドの結合方向を示します。たとえば + 演算子の結合方向は左から右 (→) なので、「a+b+c」は「(a+b)+c」と評価されます。= 演算子の結合方向は右から左 (←) なので、「a=b=c」は「a=(b=c)」と評価されます。
評価
二項以上の演算子で、どちらのオペランドから先に値が計算されるかを示します。たとえば && 演算子の評価方向は左から右 (→) なので、「(a() && b()」では a() より b() が先に計算されます。

結合方向とは異なり、多くの演算子のオペランドの評価順序は、ISO/JIS/ANSI 規格では定められていません。ISO/JIS/ANSI では、上の「評価」欄の矢印に ( ) が付いている演算の評価順序を定めていません。これらの演算については、オプションで評価順序を変更できます。-evall を指定すると「(←)」と記された演算も左オペランドから先に評価されます。

対象
演算子が受け取るオペランドの種類を示します。

各演算子についての説明

演算子説明
[n] 配列の n-1 番目の要素に評価されます。最初の要素なら 0 を指定します。
+ 整数や小数を加算できるほか、ポインタと整数を加算することができます。その結果はポインタ型になります。ポインタに 1 を足すと、ポインタの値はポイント先のサイズだけ増加します。
long* func( long* p ) {
  return p + 3; // p の実際の値に 3 * 4 = 12 を加えた値
}
- 整数や小数を減算できるほか、ポインタ同士を減算できます。その結果は int 型になります。ポインタの減算結果は、実際のアドレス値の差をポイント先のサイズで割った値になります。
char* p1 = x;
char* p2 = p1 + 12;
int dif = (long*)p2 - (long*)p1; // 結果は 12 ではなく 12 / 4 = 3
% a % bab で割ったときの剰余 (余り) を返します。この演算子は整数に適用します。小数の剰余は fmod 関数で取得できます。
<< >> a << b は a の各ビットを b 個だけ左にシフトします。右端のビットには 0 が入ります。a >> b は同様に右シフトします。符号付き値を右シフトした場合、最上位ビット (符号ビット) はシフトされずに残ります。
< <= > >= == != これらの比較演算子は、整数、浮動小数点数、ポインタに適用され、条件が成立した場合は 1、そうでない場合は 0 に評価されます。
~ & ^ | これらのビット演算子は、整数に適用され、個々のビットの論理演算結果を返します。
! && || これらの論理演算子は、整数に適用されます。0 以外に評価されるオペランドを 1、0 に評価されるオペランドを 0 として論理演算した結果を 1 または 0 で返します。
e1 ? e2 : e3 e1 が成立した場合 (0 以外に評価された場合) は e2 が評価され、そうでない場合は e3 が評価されます。
= a = bb の値を a に代入し、その値に評価されます。つまり a = b は値を持つ式であり、その上で ba に代入するという副作用を持っています。

a = ba + b などと同じように、式を使用できる任意の文脈で使用できます。
a = b = c; // b = c; a = b; と同じ
c += (a = b); // a = b; c += a; と同じ
if ( a = b ) ... // if ( a == b ) とは異なるので注意

+= -= *= /=
%=
<<= >>=
&= ^= |=
a += ba = a + b と同じです。

a <<= ba = a << b と同じです。

他の演算子も同様です。

, a, bab を順に評価し、b の値を返します。