C言語では、関数に配列を渡す際に配列のポインタを使用します。配列の名前自体がその先頭要素のポインタを示すため、関数の引数として配列名を渡すことで、配列全体を渡すことができます。
関数のプロトタイプでは、引数としてint array[]
やint *array
と記述することが一般的です。
この方法により、関数内で配列の要素を直接操作することが可能となり、メモリ効率の良いプログラムを作成できます。
- 配列を関数に渡す基本的な方法
- 配列のポインタを使った関数の実装方法
- 文字列配列や多次元配列を関数に渡す応用例
- 配列のポインタを使ったソートや検索関数の実装
- 配列のポインタと配列の違い、およびその利点
関数に配列を渡す方法
配列を関数に渡す基本
C言語では、配列を関数に渡す際に、配列そのものではなく、配列の先頭要素のポインタを渡します。
これにより、関数内で配列の要素を操作することが可能になります。
以下に基本的な例を示します。
#include <stdio.h>
// 配列を受け取る関数
void printArray(int *array, int size) {
for (int i = 0; i < size; i++) {
printf("%d ", array[i]);
}
printf("\n");
}
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int size = sizeof(numbers) / sizeof(numbers[0]);
// 配列を関数に渡す
printArray(numbers, size);
return 0;
}
1 2 3 4 5
この例では、printArray関数
に配列numbers
の先頭要素のポインタと配列のサイズを渡しています。
関数内で配列の要素を順に出力しています。
配列の要素数を渡す必要性
配列を関数に渡す際、配列の要素数を一緒に渡すことが重要です。
C言語では、配列のサイズ情報はポインタには含まれていないため、関数内で配列のサイズを知る手段がありません。
したがって、配列の要素数を引数として渡すことで、関数内で正しく配列を操作できます。
配列のポインタを渡す方法
配列のポインタを渡す方法は、配列の先頭要素のアドレスを渡すことです。
これは、配列名をそのまま渡すことで実現できます。
配列名は配列の先頭要素のポインタとして扱われます。
#include <stdio.h>
// 配列のポインタを受け取る関数
void modifyArray(int *array, int size) {
for (int i = 0; i < size; i++) {
array[i] *= 2; // 各要素を2倍にする
}
}
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int size = sizeof(numbers) / sizeof(numbers[0]);
// 配列のポインタを関数に渡す
modifyArray(numbers, size);
// 変更後の配列を出力
for (int i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
return 0;
}
2 4 6 8 10
この例では、modifyArray関数
に配列numbers
のポインタを渡し、各要素を2倍にしています。
関数内での変更は、元の配列に反映されます。
ポインタを使った配列の操作
ポインタを使って配列を操作することで、関数内で配列の要素を直接変更することができます。
ポインタを使うことで、配列の要素を効率的に操作でき、メモリの使用量を抑えることができます。
以下に、ポインタを使った配列の操作の例を示します。
#include <stdio.h>
// ポインタを使って配列を操作する関数
void reverseArray(int *array, int size) {
int *start = array;
int *end = array + size - 1;
while (start < end) {
int temp = *start;
*start = *end;
*end = temp;
start++;
end--;
}
}
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int size = sizeof(numbers) / sizeof(numbers[0]);
// 配列を逆順にする
reverseArray(numbers, size);
// 逆順後の配列を出力
for (int i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
return 0;
}
5 4 3 2 1
この例では、reverseArray関数
を使って配列を逆順にしています。
ポインタを使って配列の先頭と末尾から要素を交換することで、効率的に操作を行っています。
配列のポインタを使った関数の実装
配列のポインタを受け取る関数の宣言
配列のポインタを受け取る関数を宣言する際には、関数の引数としてポインタを指定します。
配列の要素の型に応じたポインタ型を使用し、必要に応じて配列のサイズを示す引数も追加します。
以下に基本的な宣言の例を示します。
// 配列のポインタを受け取る関数の宣言
void processArray(int *array, int size);
この宣言では、int型
の配列のポインタを受け取り、配列のサイズを示すint型
の引数を持つ関数processArray
を宣言しています。
配列のポインタを使った関数の定義
関数の定義では、宣言で指定した引数を用いて、配列のポインタを操作します。
関数内で配列の要素を操作することで、配列の内容を変更したり、特定の処理を行ったりできます。
#include <stdio.h>
// 配列のポインタを使った関数の定義
void processArray(int *array, int size) {
for (int i = 0; i < size; i++) {
array[i] += 10; // 各要素に10を加える
}
}
この定義では、processArray関数
が配列の各要素に10を加える処理を行っています。
関数内での配列操作
関数内で配列を操作する際には、ポインタを使って配列の要素にアクセスします。
ポインタを使うことで、配列の要素を直接変更することができ、効率的な操作が可能です。
#include <stdio.h>
// 配列のポインタを使った関数の定義
void processArray(int *array, int size) {
for (int i = 0; i < size; i++) {
array[i] *= 2; // 各要素を2倍にする
}
}
この例では、processArray関数
が配列の各要素を2倍にする操作を行っています。
配列のポインタを使った関数の呼び出し
配列のポインタを使った関数を呼び出す際には、配列名をそのまま渡すことで、配列の先頭要素のポインタを渡すことができます。
関数内での操作は、元の配列に反映されます。
#include <stdio.h>
// 配列のポインタを使った関数の定義
void processArray(int *array, int size) {
for (int i = 0; i < size; i++) {
array[i] += 5; // 各要素に5を加える
}
}
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int size = sizeof(numbers) / sizeof(numbers[0]);
// 配列のポインタを使った関数の呼び出し
processArray(numbers, size);
// 変更後の配列を出力
for (int i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
return 0;
}
6 7 8 9 10
この例では、processArray関数
を呼び出し、配列numbers
の各要素に5を加えています。
関数内での操作が元の配列に反映され、変更後の配列が出力されています。
応用例
文字列配列を関数に渡す
文字列配列を関数に渡す場合、各文字列は文字の配列であり、文字列配列は文字配列の配列として扱われます。
関数に渡す際には、文字列のポインタを渡します。
#include <stdio.h>
// 文字列配列を受け取る関数
void printStrings(char *strings[], int count) {
for (int i = 0; i < count; i++) {
printf("%s\n", strings[i]);
}
}
int main() {
char *fruits[] = {"Apple", "Banana", "Cherry"};
int count = sizeof(fruits) / sizeof(fruits[0]);
// 文字列配列を関数に渡す
printStrings(fruits, count);
return 0;
}
Apple
Banana
Cherry
この例では、printStrings関数
に文字列配列fruits
を渡し、各文字列を出力しています。
多次元配列を関数に渡す
多次元配列を関数に渡す場合、配列の次元数に応じたポインタを使用します。
特に、2次元配列の場合は、行のポインタを渡します。
#include <stdio.h>
// 2次元配列を受け取る関数
void printMatrix(int matrix[][3], int rows) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < 3; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
int main() {
int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
// 2次元配列を関数に渡す
printMatrix(matrix, 2);
return 0;
}
1 2 3
4 5 6
この例では、printMatrix関数
に2次元配列matrix
を渡し、行列を出力しています。
動的配列を関数に渡す
動的配列を関数に渡す場合、通常の配列と同様にポインタを渡します。
動的配列はmalloc
やcalloc
を使ってメモリを確保します。
#include <stdio.h>
#include <stdlib.h>
// 動的配列を受け取る関数
void initializeArray(int *array, int size) {
for (int i = 0; i < size; i++) {
array[i] = i + 1; // 1から始まる連続した整数で初期化
}
}
int main() {
int size = 5;
int *dynamicArray = (int *)malloc(size * sizeof(int));
if (dynamicArray == NULL) {
printf("メモリの確保に失敗しました。\n");
return 1;
}
// 動的配列を関数に渡す
initializeArray(dynamicArray, size);
// 初期化後の配列を出力
for (int i = 0; i < size; i++) {
printf("%d ", dynamicArray[i]);
}
printf("\n");
free(dynamicArray);
return 0;
}
1 2 3 4 5
この例では、initializeArray関数
に動的配列dynamicArray
を渡し、配列を初期化しています。
配列のポインタを使ったソート関数
配列のポインタを使ってソート関数を実装することで、配列の要素を並べ替えることができます。
以下にバブルソートを用いた例を示します。
#include <stdio.h>
// 配列のポインタを使ったソート関数
void bubbleSort(int *array, int size) {
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - i - 1; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
int main() {
int numbers[] = {5, 3, 8, 6, 2};
int size = sizeof(numbers) / sizeof(numbers[0]);
// 配列のポインタを使ったソート関数の呼び出し
bubbleSort(numbers, size);
// ソート後の配列を出力
for (int i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
return 0;
}
2 3 5 6 8
この例では、bubbleSort関数
を使って配列numbers
を昇順にソートしています。
配列のポインタを使った検索関数
配列のポインタを使って検索関数を実装することで、特定の要素を配列内から探すことができます。
以下に線形探索を用いた例を示します。
#include <stdio.h>
// 配列のポインタを使った検索関数
int linearSearch(int *array, int size, int target) {
for (int i = 0; i < size; i++) {
if (array[i] == target) {
return i; // 見つかった場合のインデックスを返す
}
}
return -1; // 見つからなかった場合
}
int main() {
int numbers[] = {5, 3, 8, 6, 2};
int size = sizeof(numbers) / sizeof(numbers[0]);
int target = 6;
// 配列のポインタを使った検索関数の呼び出し
int index = linearSearch(numbers, size, target);
if (index != -1) {
printf("要素%dはインデックス%dにあります。\n", target, index);
} else {
printf("要素%dは配列に存在しません。\n", target);
}
return 0;
}
要素6はインデックス3にあります。
この例では、linearSearch関数
を使って配列numbers
から要素6
を探し、そのインデックスを出力しています。
見つからない場合は-1
を返します。
よくある質問
まとめ
配列のポインタを使って関数に配列を渡す方法は、C言語プログラミングにおいて重要な技術です。
この記事では、配列のポインタを使った関数の実装方法や応用例について詳しく解説しました。
これにより、効率的なメモリ管理と配列操作が可能になります。
この記事を参考に、実際のプログラムで配列のポインタを活用してみてください。