C言語のXOR演算を完全解説|基本から応用まで徹底ガイド

1. 導入

C言語でのビット演算の概要

C言語は、メモリやプロセッサを効率的に扱うためにビット演算を提供しています。その中でも特に重要なものが「XOR(排他的論理和)」です。ビット演算は通常、データの暗号化、データの検証、数値操作など、さまざまな場面で利用されます。XORは、2つのビットが異なる場合に「1」を、同じ場合には「0」を返す特性を持ち、シンプルかつ強力な演算として知られています。

この記事では、C言語におけるXOR演算の基礎から応用までを順に説明します。実際のコード例を交えて、初心者でも理解しやすいように構成されています。

2. XOR演算子の基本

XORとは?

XOR(排他的論理和)は、ビットごとに2つの数値を比較し、それぞれのビットが異なる場合に「1」を、同じ場合には「0」を返します。たとえば、以下のように数値5と9のビットごとの比較を行うと、XOR演算の結果が得られます。

  • 5の2進数: 0101
  • 9の2進数: 1001

このビットをXOR演算で比較すると、以下のようになります。

ビット位置5 (0101)9 (1001)XOR結果
1011
2101
3000
4110

結果は 1100 となり、これは10進数で「12」です。このXOR演算の基本的な動作を理解することで、より複雑なビット演算にも応用することができます。

3. サンプルコードで理解するXOR

基本的なXORの使用例

C言語におけるXOR演算を実行する簡単な例を以下に示します。このコードは、数値5と9に対してXOR演算を行い、その結果を表示します。

#include <stdio.h>

int main() {
    int a = 5;
    int b = 9;
    int result = a ^ b;

    printf("5 XOR 9 = %d\n", result);  // 結果は12
    return 0;
}

このコードは、数値 ab のビットごとのXORを計算し、結果が result に保存されます。実行すると、「5 XOR 9 = 12」と表示されます。ビットごとの演算を視覚的に理解するための良い例です。

4. XORの応用例

XORを使った変数の値の交換

XORのユニークな特性を利用することで、2つの変数の値を一時変数を使わずに交換できます。以下のコードは、XORを用いて2つの変数 ab の値を交換する方法を示しています。

#include <stdio.h>

int main() {
    int a = 5;
    int b = 7;

    printf("Before swap: a = %d, b = %d\n", a, b);

    a = a ^ b;
    b = a ^ b;
    a = a ^ b;

    printf("After swap: a = %d, b = %d\n", a, b);
    return 0;
}

このコードでは、XORを3回使用することで、ab の値を効率的に交換しています。これにより、一時変数を使わずに値を入れ替えることができ、メモリの節約につながります。

5. 実用例と応用範囲

配列内の重複する数字や奇数回出現する数字の検出

XORは、配列内の重複する要素や奇数回出現する要素を効率的に検出することもできます。以下に、重複した要素を検出する例と、奇数回出現する要素を見つけるコードを示します。

重複した数字の発見

#include <stdio.h>

int findDuplicate(int nums[], int size) {
    int duplicate = 0;
    for (int i = 0; i < size; i++) {
        duplicate ^= nums[i];
    }
    return duplicate;
}

int main() {
    int nums[] = {1, 2, 3, 2, 4};
    int size = sizeof(nums) / sizeof(nums[0]);

    printf("Duplicate number is: %d\n", findDuplicate(nums, size));
    return 0;
}

このコードでは、XORを使って配列内で重複した数値を検出します。XORの特性を利用して、同じ数値を二度XORすると0になり、重複する数値だけが結果に残ります。

奇数回出現する数字の検出

#include <stdio.h>

int findOddOccurrence(int nums[], int size) {
    int result = 0;
    for (int i = 0; i < size; i++) {
        result ^= nums[i];
    }
    return result;
}

int main() {
    int nums[] = {5, 3, 9, 3, 5, 9, 7};
    int size = sizeof(nums) / sizeof(nums[0]);

    printf("Odd occurring number is: %d\n", findOddOccurrence(nums, size));
    return 0;
}

このコードでは、奇数回出現する数字だけが最終的にXORの結果に残るため、簡単に検出できます。

データ暗号化におけるXORの利用

XORはデータ暗号化にも使用されます。以下のコードでは、XORを用いた簡単な暗号化と復号化の例を示しています。

#include <stdio.h>

void encryptDecrypt(char data[], char key) {
    for (int i = 0; data[i] != '\0'; i++) {
        data[i] = data[i] ^ key;
    }
}

int main() {
    char data[] = "Hello World";
    char key = 'K';

    printf("Original: %s\n", data);
    encryptDecrypt(data, key);
    printf("Encrypted: %s\n", data);
    encryptDecrypt(data, key);
    printf("Decrypted: %s\n", data);

    return 0;
}

このコードでは、データに対してXOR演算を適用することで、暗号化と復号化が行われます。XORを再度適用することで元のデータに戻るため、シンプルな暗号化技術として利用されます。

6. まとめ

この記事では、C言語におけるXOR演算の基本的な使い方から応用例までを解説しました。XORは、データの暗号化やエラーチェック、プログラムの最適化、ハッシュ関数の設計など、幅広い分野で活用されています。特にその高速性と効率性により、大規模なデータ処理やパフォーマンスを求められる場面で重要な役割を果たします。

この記事を通じて、XOR演算がどれほど強力なツールであるかを理解し、今後のプログラミングに役立てていただければ幸いです。