1. 算術演算子
C 言語において最も基本的な数学的処理を行うのは以下の演算子です。
- 加算
+ - 減算
- - 乗算
* - 除算
/ - 剰余
%
これらは両側にあるオペランド(数値や変数)に対して作用し、計算結果を返します。
除算 (/) の挙動に関する注意
特に注意が必要なのが除算です。演算子が分割する両側がどちらか一方でも浮動小数点数型でない場合、整数除算が行われます。
#include <stdio.h>
int main() {
// 整数同士の除算
double result_int = 7 / 2;
printf("整数除算の結果:%.1f\n", result_int);
// 少なくとも片方が実数の場合
double result_float = 7.0 / 2;
printf("浮動除算の結果:%.1f\n", result_float);
return 0;
}
上のコードでわかる通り、両方が整数(int)の場合、結果は小数点以下が切り捨てられた整数になります(この例では 3.0 として表示されます)。計算結果を正確な浮動値として得るには、オペランドのいずれかを浮動小数点数形式に変換する必要があります。一般的に、%f はデフォルトで小数点以下 6 桁を表示します。
剰余演算子 (%) の仕様
剰余演算子は割ったあまりを求めます。ただし、これは整数型に限定されます。
負数が絡む場合、結果の符号は左辺のオペランドの符号に追随します。
printf("%d\n", -10 % 3); // 結果:-1 (左辺が負)
printf("%d\n", 10 % -3); // 結果:1 (左辺が正)
2. シフト演算子
ビット列を論理または算数的に移動させるために使用されます。
<<: 左シフト(矢印の方向へ移動)>>: 右シフト(矢印の方向へ移動)
これらの演算子は元の値を変更しないため、代入式を使用する必要があります。
#include <stdio.h>
int main() {
int base_val = 8; // 2進数: 1000
int moved_left;
// 左に 1 ビットシフト (2 倍になる効果)
moved_left = base_val << 1;
printf("シフト後の値:%d\n", moved_left); // 出力:16
return 0;
}
重要な挙動と警告
左シフト (<<) は常に左端ビットが捨てられ、右側に 0 が埋められます。右シフト (>>) については、環境依存性が高く、論理シフト(符号位に関わらず 0 で埋める)か算術シフト(符号位を複製して埋める)かはコンパイラの実装によります。多くの現代的な C 実装では、符号あり整数值に対する右シフトは算術シフトを採用しています。
禁止事項:
- シフト量の指定が負数であること(例:
<< -1)。 - シフト量がデータ型のビット幅を超えていること(例:32 ビット整数に対し 100 ビットシフト)。
3. ビット演算子
これらの演算子は、整数の二進数表現(2 補数形式)に対して個々のビット単位で処理を行います。
- アンド (
&): 両方のビットが 1 のとき 1 を返す。 - エクスクルーシブ オア (
^): どちらか一方だけが 1 のとき 1 を返す。 - オア (
|): どちらかが 1 なら 1 を返す。 - ノット (
~): 各ビットの反転を行う。
※浮動小数点数や文字以外のデータ型では定義が定まっていませんので、整数型に限定してください。
4. 代入演算子
値を記憶するために用います。複合代入演算子は簡潔な書き方を可能にします。
- 連立代入:
a = b = c = 10;(右から左へ評価される) - 複合代入:
x += 5;はx = x + 5;と等価です。
これらは加算、減算、乗算、除算、剰余などの後方に = を付けた形が存在します(*=, /=, %= など)。
5. 単項演算子
単一オペランド作用于する演算子群です。
論理否定 (!)
C 言語では「0」が偽(False)、0 以外は真(True)として扱われます。! は真理値を逆転させます。
int val = 0;
if (!val) {
/* val が 0 の場合はここが実行される */
}
符号演算子 (+,-)
値のプラスまたはマイナスを示します。
サイズ取得演算子 (sizeof)
型や変数に割り当てられたメモリアドレス空間のバイト数を取得します。