C言語の演算子と式の種類を徹底解説!算術からビット演算まで
C言語における演算子(オペレーター)とは、データに対して何らかの操作を行うための記号です。C言語の演算子は、その機能によって以下のように分類されます。
- 算術演算子
- 関係演算子
- 論理演算子
- 代入演算子
- インクリメント・デクリメント演算子
- ビット演算子
- 条件演算子
- 特殊演算子
それぞれの演算子について、具体例とサンプルプログラムを交えながら詳しく見ていきましょう。
1. 算術演算子
算術演算子は、足し算や引き算などの数値計算を行うために使われます。
| 演算子 | 説明 | 例 | a=20, b=10 の場合 | 結果 |
|---|---|---|---|---|
| + | 加算(足し算) | a+b | 20+10 | 30 |
| - | 減算(引き算) | a-b | 20-10 | 10 |
| * | 乗算(掛け算) | a*b | 20*10 | 200 |
| / | 除算(割り算) | a/b | 20/10 | 2(商) |
| % | 剰余演算(余り) | a%b | 20%10 | 0(余り) |
サンプルプログラム
#include <stdio.h>
int main(void) {
int a = 20, b = 10;
printf("%d\n", a + b);
printf("%d\n", a - b);
printf("%d\n", a * b);
printf("%d\n", a / b);
printf("%d\n", a % b);
return 0;
}実行結果
30 10 200 2 0
2. 関係演算子
関係演算子は、2つの式の大小関係や等価性を比較するために使われます。比較の結果は「真(true)=1」または「偽(false)=0」で返されます。
| 演算子 | 説明 | 例 | a=10, b=20 の場合 | 結果 |
|---|---|---|---|---|
| < | より小さい | a<b | 10<20 | 1 |
| <= | 以下 | a<=b | 10<=20 | 1 |
| > | より大きい | a>b | 10>20 | 0 |
| >= | 以上 | a>=b | 10>=20 | 0 |
| == | 等しい | a==b | 10==20 | 0 |
| != | 等しくない | a!=b | 10!=20 | 1 |
サンプルプログラム
#include <stdio.h>
int main(void) {
int a = 10, b = 20;
printf("%d ", a < b);
printf("%d ", a <= b);
printf("%d ", a > b);
printf("%d ", a >= b);
printf("%d ", a == b);
printf("%d ", a != b);
return 0;
}実行結果
1 1 0 0 0 1
3. 論理演算子
論理演算子は、2つ以上の条件式を組み合わせるために使われます。C言語には「論理AND(&&)」「論理OR(||)」「論理NOT(!)」の3種類があります。
論理AND(&&)の真理値表
| exp1 | exp2 | exp1&&exp2 |
|---|---|---|
| T | T | T |
| T | F | F |
| F | T | F |
| F | F | F |
論理OR(||)の真理値表
| exp1 | exp2 | exp1||exp2 |
|---|---|---|
| T | T | T |
| T | F | T |
| F | T | T |
| F | F | F |
論理NOT(!)の真理値表
| exp | !exp |
|---|---|
| T | F |
| F | T |
使用例
| 演算子 | 説明 | 例 | a=10, b=20, c=30 の場合 | 結果 |
|---|---|---|---|---|
| && | 論理AND | (a>b)&&(a<c) | (10>20)&&(10<30) | 0 |
| || | 論理OR | (a>b)||(a<c) | (10>20)||(10<30) | 1 |
| ! | 論理NOT | !(a>b) | !(10>20) | 1 |
サンプルプログラム
#include <stdio.h>
int main(void) {
int a = 10, b = 20, c = 30;
printf("%d ", (a > b) && (a < c));
printf("%d ", (a > b) || (a < c));
printf("%d ", !(a > b));
return 0;
}実行結果
0 1 1
4. 代入演算子
代入演算子は、変数に値を格納するために使われます。単純代入と複合代入の2種類があります。
| 演算子 | 説明 | 例 |
|---|---|---|
| = | 単純代入 | a = 10 |
| +=, -=, *=, /=, %= | 複合代入 | a += 10 は a = a + 10 と同じ a -= 10 は a = a - 10 と同じ |
サンプルプログラム
#include <stdio.h>
int main(void) {
int a = 10;
printf("%d\n", a);
a += 10;
printf("%d\n", a);
return 0;
}実行結果
10 20
5. インクリメント・デクリメント演算子
インクリメント演算子(++)
変数の値を1増加させる演算子です。「前置インクリメント」と「後置インクリメント」の2種類があります。
- 前置インクリメント(++a): 値を先に1増やしてから、その後の処理に使われます。
z = ++a;はa = a + 1;の後z = a;と同じ意味です。 - 後置インクリメント(a++): 処理に現在の値を使った後で、値が1増やされます。
z = a++;はz = a;の後a = a + 1;と同じ意味です。
前置と後置の違いを確認するプログラム
main() {
int a = 10, z;
z = ++a;
printf("z=%d\n", z);
printf("a=%d\n", a);
} | main() {
int a = 10, z;
z = a++;
printf("z=%d\n", z);
printf("a=%d\n", a);
} |
| 実行結果 | 実行結果 |
z=11 a=11 | z=10 a=11 |
デクリメント演算子(--)
変数の値を1減少させる演算子です。こちらも「前置デクリメント」と「後置デクリメント」の2種類があります。
- 前置デクリメント(--a): 値を先に1減らしてから、その後の処理に使われます。
z = --a;はa = a - 1;の後z = a;と同じ意味です。 - 後置デクリメント(a--): 処理に現在の値を使った後で、値が1減らされます。
z = a--;はz = a;の後a = a - 1;と同じ意味です。
前置と後置の違いを確認するプログラム
main() {
int a = 10, z;
z = --a;
printf("z=%d\n", z);
printf("a=%d\n", a);
} | main() {
int a = 10, z;
z = a--;
printf("z=%d\n", z);
printf("a=%d\n", a);
} |
| 実行結果 | 実行結果 |
z=9 a=9 | z=10 a=9 |
6. ビット演算子
ビット演算子は、データをビット単位で操作するために使われます。
| 演算子 | 説明 |
|---|---|
| & | ビットごとのAND |
| | | ビットごとのOR |
| ^ | ビットごとのXOR(排他的論理和) |
| << | 左シフト |
| >> | 右シフト |
| ~ | 1の補数(ビット反転) |
ビットごとのAND(&)の真理値表
| a | b | a&b |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
ビットごとのOR(|)の真理値表
| a | b | a|b |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
ビットごとのXOR(^)の真理値表
| a | b | a^b |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
サンプルプログラム
#include <stdio.h>
int main(void) {
int a = 12, b = 10;
printf("%d ", a & b);
printf("%d ", a | b);
printf("%d ", a ^ b);
return 0;
}実行結果
8 14 6
左シフト(<<)
値を1回左シフトすると、元の値は2倍になります。たとえば a = 10 のとき、a << 1 は 20 になります。
右シフト(>>)
値を1回右シフトすると、元の値は半分になります。たとえば a = 10 のとき、a >> 1 は 5 になります。
1の補数(~)
すべてのビットを反転させます(1は0に、0は1になります)。たとえば a = 5 の場合、4ビットで考えると ~a は 2 になります。
シフトと補数のサンプルプログラム
#include <stdio.h>
int main(void) {
int a = 20, b = 10, c = 10;
printf("%d\n", a << 1);
printf("%d\n", b >> 1);
printf("%d\n", ~c);
return 0;
}実行結果
40 5 -11
符号付き整数の場合
1の補数は「-(与えた数 + 1)」として計算されます。
- ~10 = -(10+1) = -11
- ~-10 = -(-10+1) = 9
符号なし整数の場合
1の補数は「65535 - 与えた数」として計算されます(16ビットの場合)。
7. 条件演算子(? :)
条件演算子は「三項演算子」とも呼ばれ、C言語で唯一の3項を取る演算子です。if-else文を1行で簡潔に書くことができます。
構文
exp1 ? exp2 : exp3
exp1が真であればexp2が評価され、偽であればexp3が評価されます。これは次のif-else文と同等です。
if (exp1)
exp2;
else
exp3;サンプルプログラム
#include <stdio.h>
int main(void) {
int z;
z = (5 > 3) ? 1 : 0;
printf("%d\n", z);
return 0;
}実行結果
1
8. 特殊演算子
C言語には、上記以外にも便利な特殊な演算子がいくつか用意されています。
- カンマ演算子(,): 変数などを区切るセパレータとして使われます。例:a = 10, b = 20
- アドレス演算子(&): 変数のメモリアドレスを取得します。
- sizeof演算子: データ型や変数のサイズをバイト単位で取得します。
サンプルプログラム
#include <stdio.h>
int main(void) {
int a = 10;
float b = 20;
printf("a=%d b=%f\n", a, b);
printf("aのアドレス = %u\n", &a);
printf("bのアドレス = %u\n", &b);
printf("aのサイズ = %ldバイト\n", sizeof(a));
printf("bのサイズ = %ldバイト\n", sizeof(b));
return 0;
}実行結果(環境により異なります)
a=10 b=20.000000 aのアドレス = 1234 bのアドレス = 5678 aのサイズ = 4バイト bのサイズ = 4バイト
まとめ
C言語の演算子は、算術・関係・論理・代入・インクリメント/デクリメント・ビット・条件・特殊の8種類に分類できます。それぞれの演算子の動作を正しく理解することで、より効率的で読みやすいコードを書けるようになります。特に前置と後置のインクリメント/デクリメントの違いや、ビット演算の挙動は初心者がつまずきやすいポイントなので、実際にプログラムを動かしながら確実に身につけていきましょう。
-
C言語で評価される式の種類とは?6種類の式を徹底解説
C言語における「式」とは?式(expression)とは、演算子とオペランドを組み合わせたものを指します。オペランドは演算の対象となるデータ項目であり、演算子はそのデータに対して具体的な操作を実行する役割を担います。例えば、次のような式を見てみましょう。z = 3 + 2 * 1 z = 5この場合、「3」「2」「1」がオペランドであり、「*」(乗算)や「+」(加算)が演算子として機能し、最終的に z には 5 が代入されます。C言語で使われる式の種類C言語で評価される式には、主に以下の6種類があります。1. 主式(一次式 / Primary Expressions)オペランドが識別子(変数名
-
C言語の探索アルゴリズム解説|線形探索と二分探索の違いと実装例
探索(サーチ)とは、複数の要素で構成されるリストの中から、目的の「キー」となる要素を見つけ出す処理のことです。 リストの中に指定した要素が存在すれば、その探索は「成功」とみなされます。 指定した要素がリストに存在しなければ、その探索は「失敗(不成功)」となります。 C言語で広く使われている代表的な探索手法は、主に次の2つです。 線形探索(Linear Search/リニアサーチ) 二分探索(Binary Search/バイナリサーチ) 線形探索(Linear Search)とは 線形探索は、リストの先頭から順に要素を1つずつ取り出し、キーと一致するかどうかを確認していく、最も基本的な探