C言語で利用される様々な演算子について解説します。
算術演算子
基本的な算術演算を行います。
+(加算)-(減算)*(乗算)/(除算)%(剰余)
整数同士の除算では小数点以下は切り捨てられます。剰余演算子は、除算の余りを求めます。
#include <stdio.h>
int main() {
int quotient = 9 / 2; // 結果は4 (整数除算)
printf("Quotient: %d\n", quotient);
float preciseQuotient = 9.0f / 2.0f; // 結果は4.5
printf("Precise Quotient: %f\n", preciseQuotient);
int remainder = 9 % 2; // 結果は1
printf("Remainder: %d\n", remainder);
return 0;
}
シフト演算子
ビット列を左右にシフトさせます。
<<(左シフト)>>(右シフト)
これらの演算子は、オペランドの2進数表現をビット単位で操作します。
#include <stdio.h>
int main() {
int value = 2; // 2進数で 0010
int shiftedValue = value << 1; // 1ビット左にシフト -> 0100 (10進数で4)
printf("Shifted value: %d\n", shiftedValue); // 出力: 4
return 0;
}
ビット演算子
ビット単位での論理演算を行います。
&(ビット単位AND)|(ビット単位OR)^(ビット単位XOR)
代入演算子
値の代入や、計算結果の代入を行います。
=(代入)+=(加算して代入)-=(減算して代入)*=(乗算して代入)/=(除算して代入)&=(ビット単位ANDして代入)^=(ビット単位XORして代入)|=(ビット単位ORして代入)>>=(右シフトして代入)<<=(左シフトして代入)
#include <stdio.h>
int main() {
int count = 5;
count += 3; // count は 8 になる (count = count + 3 と同じ)
printf("count after +=: %d\n", count);
int data = 10;
data %= 3; // data は 1 になる (data = data % 3 と同じ)
printf("data after %%=: %d\n", data);
return 0;
}
単項演算子
一つのオペランドに対して作用する演算子です。
!(論理否定)-(符号反転)+(符号そのまま)&(アドレス演算子)sizeof(サイズ演算子)~(ビット単位否定)--(デクリメント)++(インクリメント)*(間接参照演算子 / デリファレンス演算子)(型)(キャスト演算子 / 型変換)
C言語では、0 は偽、非0 は真とみなされます。
1. 論理否定 (!)
オペランドの真偽を反転させます。
#include <stdio.h>
int main() {
int flag = 0; // 偽
int invertedFlag = !flag; // 真 (1) になる
printf("Original flag: %d, Inverted flag: %d\n", flag, invertedFlag);
return 0;
}
2. sizeof 演算子
オペランドのメモリ上のサイズをバイト単位で返します。
#include <stdio.h>
int main() {
printf("Size of int: %zu bytes\n", sizeof(int));
printf("Size of float: %zu bytes\n", sizeof(float));
int numbers[5];
printf("Size of array 'numbers': %zu bytes\n", sizeof(numbers));
printf("Size of one element in 'numbers': %zu bytes\n", sizeof(numbers[0]));
// 配列の要素数を計算
size_t elementCount = sizeof(numbers) / sizeof(numbers[0]);
printf("Number of elements in 'numbers': %zu\n", elementCount);
return 0;
}
3. ビット単位否定 (~)
オペランドの各ビットを反転させます (0を1に、1を0に)。
整数は、符号ビットを含む3つの表現形式(原码、反码、補码)で扱われます。コンピュータは通常、補码で整数を格納します。
#include <stdio.h>
int main() {
int val = 0; // 2進数で ...00000000
// ~val は、すべてのビットが反転するので ...11111111 (補码表現で -1)
printf("Bitwise NOT of 0: %d\n", ~val); // 出力: -1
int num = 5; // 2進数で ...00000101
// ~num は ...11111010 (補码表現で -6)
printf("Bitwise NOT of 5: %d\n", ~num); // 出力: -6
return 0;
}
4. インクリメント/デクリメント (++ / --)
オペランドの値を1増減させます。前置と後置で動作が異なります。
前置インクリメント (++variable)
先に値をインクリメントし、その後、インクリメントされた値を使用します。
#include <stdio.h>
int main() {
int counter = 10;
int result = ++counter; // counter が 11 になり、その値 (11) が result に代入される
printf("Counter: %d, Result: %d\n", counter, result); // 出力: Counter: 11, Result: 11
return 0;
}
後置インクリメント (variable++)
先に元の値を使用し、その後、値をインクリメントします。
#include <stdio.h>
int main() {
int counter = 10;
int result = counter++; // counter の元の値 (10) が result に代入され、その後 counter が 11 になる
printf("Counter: %d, Result: %d\n", counter, result); // 出力: Counter: 11, Result: 10
return 0;
}
5. キャスト演算子 ((型))
明示的にデータ型を変換します。
#include <stdio.h>
int main() {
// 浮動小数点数を整数型に変換 (小数点以下は切り捨てられる)
int intValue = (int)3.14159;
printf("Casted int value: %d\n", intValue); // 出力: 3
return 0;
}
関係演算子
二つのオペランドを比較し、真偽 (1または0) を返します。
>(より大きい)>=(以上)<(より小さい)<=(以下)!=(等しくない)==(等しい)
論理演算子
オペランドの真偽に基づいて、論理的なANDまたはOR演算を行います。
&&(論理AND)||(論理OR)
#include <stdio.h>
int main() {
int conditionA = 5; // 真
int conditionB = 0; // 偽
int logicalAND = conditionA && conditionB; // 両方真ではないので偽 (0)
printf("Logical AND: %d\n", logicalAND);
int logicalOR = conditionA || conditionB; // Aが真なので真 (1)
printf("Logical OR: %d\n", logicalOR);
return 0;
}
条件演算子 (三項演算子)
3つのオペランドを取り、条件に基づいて値を返します。
条件式 ? 真の場合の値 : 偽の場合の値
#include <stdio.h>
int main() {
int x = 10;
int y = 20;
int largerValue;
// if-else 文での実装
if (x > y) {
largerValue = x;
} else {
largerValue = y;
}
printf("Larger value (if-else): %d\n", largerValue);
// 三項演算子での実装
largerValue = (x > y) ? x : y;
printf("Larger value (ternary operator): %d\n", largerValue); // 出力: 20
return 0;
}
カンマ演算子
複数の式を左から右へ順に評価し、最後の式の値を返します。
式1, 式2, 式3, ...
#include <stdio.h>
int main() {
int a = 1;
int b = 5;
int c = 10;
// (a = b + 2) -> a は 7 になる
// (c = a - 4) -> c は 3 になる
// (b = c + 2) -> b は 5 になる
// カンマ式全体の結果は最後の式 (b = c + 2) の結果、つまり 5 になる
int result = (a = b + 2, c = a - 4, b = c + 2);
printf("a: %d, b: %d, c: %d, result: %d\n", a, b, c, result);
// 出力: a: 7, b: 5, c: 3, result: 5
return 0;
}
配列要素アクセス、関数呼び出し、構造体メンバーアクセス
[](配列添字演算子)()(関数呼び出し演算子).(構造体メンバーアクセス演算子)->(構造体ポインタメンバーアクセス演算子)
1. 配列添字演算子 ([])
配列の指定したインデックスの要素にアクセスします。
#include <stdio.h>
int main() {
int dataArray[5] = {10, 20, 30, 40, 50};
// dataArray[2] は 3 番目の要素 (値は 30) にアクセス
printf("Element at index 2: %d\n", dataArray[2]); // 出力: 30
return 0;
}
2. 関数呼び出し演算子 (())
関数を実行します。
#include <stdio.h>
// 簡単な関数定義
void greet() {
printf("Hello from greet function!\n");
}
int add(int x, int y) {
return x + y;
}
int main() {
greet(); // greet 関数を呼び出す
int sum = add(15, 25); // add 関数を呼び出し、結果を sum に代入
printf("Sum of 15 and 25: %d\n", sum); // 出力: 40
return 0;
}