C言語で一時変数を使わずに2つの配列を交換する方法【サンプルコード付き】
C言語で2つの配列の内容を入れ替える(スワップする)場合、一般的には一時変数(テンポラリ変数)を介して値を交換します。しかし、算術演算子やビット演算子を工夫して使えば、第3の変数を一切用意せずに配列同士を交換することも可能です。
本記事では、加減算を利用したスワップ手法を中心に、入力処理からスワップ処理、完全なサンプルコードと実行結果までを順番に解説します。
スワップの基本原理:加減算による値の交換
2つの整数 a と b を一時変数なしで入れ替えるには、次の3ステップの加減算を利用します。
a = a + b; /* a に合計値を代入 */ b = a - b; /* 合計から元の b を引くと、元の a が求まる */ a = a - b; /* 合計から新しい b(= 元の a)を引くと、元の b が求まる */
この考え方を配列に応用し、各要素に対して同じ操作を繰り返すことで、配列全体を入れ替えることができます。
1つ目の配列を読み込む処理
printf("1つ目の配列の要素を入力:\n");
for(i = 0; i < size; i++){
scanf("%d", &first[i]);
}
2つ目の配列を読み込む処理
printf("2つ目の配列の要素を入力:\n");
for(i = 0; i < size; i++){
scanf("%d", &sec[i]);
}
一時変数を使わないスワップ処理
for(i = 0; i < size; i++){
first[i] = first[i] + sec[i];
sec[i] = first[i] - sec[i];
first[i] = first[i] - sec[i];
}
ループ内の3行の処理によって、first[i] と sec[i] の値が互いに入れ替わります。
プログラム全体
以下は、一時変数を使用せずに2つの配列を交換するC言語プログラムの完全なコードです。
#include <stdio.h>
int main(void){
int size, i, first[20], sec[20];
printf("配列のサイズを入力してください:");
scanf("%d", &size);
printf("1つ目の配列の要素を入力してください:\n");
for(i = 0; i < size; i++){
scanf("%d", &first[i]);
}
printf("2つ目の配列の要素を入力してください:\n");
for(i = 0; i < size; i++){
scanf("%d", &sec[i]);
}
/* 一時変数を使わずに2つの配列を交換 */
for(i = 0; i < size; i++){
first[i] = first[i] + sec[i];
sec[i] = first[i] - sec[i];
first[i] = first[i] - sec[i];
}
printf("\n交換後の1つ目の配列(%d個の要素):\n", size);
for(i = 0; i < size; i++){
printf(" %d \t ", first[i]);
}
printf("\n交換後の2つ目の配列(%d個の要素):\n", size);
for(i = 0; i < size; i++){
printf(" %d \t ", sec[i]);
}
return 0;
}
実行結果
上記のプログラムを実行すると、次のような出力が得られます。
配列のサイズを入力してください:5 1つ目の配列の要素を入力してください: 11 12 13 14 15 2つ目の配列の要素を入力してください: 90 80 70 60 50 交換後の1つ目の配列(5個の要素): 90 80 70 60 50 交換後の2つ目の配列(5個の要素): 11 12 13 14 15
実行結果から、2つの配列の内容が完全に入れ替わっていることが確認できます。
補足:XOR(排他的論理和)を使ったスワップ方法
ビット演算子であるXOR(^)を利用しても、同じく一時変数なしでスワップが実現できます。
for(i = 0; i < size; i++){
first[i] ^= sec[i];
sec[i] ^= first[i];
first[i] ^= sec[i];
}
XOR方式は中間計算で値が大きくならないため、オーバーフローを気にせずに済むのが利点です。一方で、加減算方式に比べると動作が直感的に理解しにくいという側面もあります。
注意点
加減算によるスワップでは、途中で「a + b」という合計値を計算するため、要素の合計がint型の表現範囲を超えるとオーバーフローの恐れがあります。大きな値を扱う可能性がある場合は、より大きなデータ型(long long など)を使用するか、XOR方式を採用すると安全です。
-
【初心者向け】C言語のポインタを使って配列要素の合計を計算する方法
ポインタとは?ポインタ(Pointer)とは、他の変数のアドレス(メモリ上の場所)を格納するための変数のことです。例えば、次のような変数宣言を見てみましょう。int qty = 179;この場合、変数 qty には値 179 が格納されています。ポインタは、この qty が配置されているメモリ上のアドレスを保持することができます。ポインタの宣言ポインタを宣言する構文は以下の通りです。int *p;ここで p はポインタ変数であり、他の int 型変数のアドレスを保持します。宣言時には、変数名の前に間接演算子 *(アスタリスク)を付けます。ポインタの初期化ポインタ変数を初期化するには、アドレス演
-
C言語の線形探索で配列内の最小値を見つける方法を徹底解説
C言語の探索アルゴリズムの種類C言語で使われる代表的な探索手法は、大きく分けて以下の2つです。線形探索(リニアサーチ)二分探索(バイナリサーチ)線形探索とは線形探索は、配列の先頭から順番に要素を一つずつ比較しながら目的のキーを探す、最も基本的な探索アルゴリズムです。データがソート(整列)されていなくても使用できる実装が非常にシンプルで理解しやすい欠点:データ数が多いほど処理時間が長くなり、システムの効率を低下させる可能性がある入出力のイメージは以下の通りです。入力:ソートされていない要素のリスト、探索キー出力:・成功 … キーが見つかった場合・失敗 … キーが見つからなかった場合例1:線形探索