[C言語] 関数に配列を渡して値を書き換える方法を解説
C言語では、配列を関数に渡す際に配列の先頭アドレスが渡されます。これにより、関数内で配列の要素を直接書き換えることが可能です。
関数の引数として配列を指定する際には、配列の型とサイズを指定する必要はなく、ポインタとして渡されます。
例えば、void modifyArray(int arr[], int size)
のように関数を定義し、関数内でarr[i] = newValue
とすることで、元の配列の値を変更できます。
この特性を利用することで、効率的にデータを操作することができます。
- 配列のアドレスを関数に渡す方法とその重要性
- ポインタを使った配列の値の書き換え方法
- 多次元配列や動的メモリ割り当ての活用法
- 配列のソートやフィルタリングの実践的な手法
関数に配列を渡す方法
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
この例では、numbers
という配列の先頭アドレスをprintArray関数
に渡しています。
関数内で配列の要素を表示しています。
配列の要素数を渡す必要性
配列を関数に渡す際には、配列の要素数も一緒に渡すことが重要です。
C言語では配列のサイズ情報が自動的に渡されないため、関数内で配列のサイズを知るためには、要素数を引数として渡す必要があります。
ポインタを使った配列の受け取り方
関数で配列を受け取る際には、ポインタを使って受け取ります。
配列名は配列の先頭アドレスを指しているため、ポインタを使うことで配列の要素にアクセスできます。
#include <stdio.h>
// 配列の要素を2倍にする関数
void doubleArray(int *array, int size) {
for (int i = 0; i < size; i++) {
array[i] *= 2;
}
}
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int size = sizeof(numbers) / sizeof(numbers[0]);
// 配列のアドレスを渡して要素を2倍にする
doubleArray(numbers, size);
// 結果を表示
for (int i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
return 0;
}
2 4 6 8 10
この例では、doubleArray関数
で配列の各要素を2倍にしています。
ポインタを使って配列の要素を直接操作しています。
配列の値を書き換える方法
C言語では、配列の値を関数内で書き換えることができます。
ここでは、ポインタを使った値の書き換えや、関数内での配列操作について詳しく解説します。
ポインタを使った値の書き換え
配列の値を変更する際には、ポインタを使うことで直接配列の要素にアクセスし、値を変更することができます。
ポインタを使うことで、関数内で配列の要素を効率的に操作できます。
#include <stdio.h>
// 配列の要素を3倍にする関数
void tripleArray(int *array, int size) {
for (int i = 0; i < size; i++) {
*(array + i) *= 3; // ポインタを使って値を変更
}
}
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int size = sizeof(numbers) / sizeof(numbers[0]);
// 配列のアドレスを渡して要素を3倍にする
tripleArray(numbers, size);
// 結果を表示
for (int i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
return 0;
}
3 6 9 12 15
この例では、tripleArray関数
でポインタを使って配列の各要素を3倍にしています。
関数内での配列の操作
関数内で配列を操作する際には、配列のアドレスを渡すことで、関数内で直接配列の要素を変更することができます。
これにより、関数外でも変更が反映されます。
#include <stdio.h>
// 配列の要素を負の値にする関数
void negateArray(int *array, int size) {
for (int i = 0; i < size; i++) {
array[i] = -array[i];
}
}
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int size = sizeof(numbers) / sizeof(numbers[0]);
// 配列のアドレスを渡して要素を負の値にする
negateArray(numbers, size);
// 結果を表示
for (int i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
return 0;
}
-1 -2 -3 -4 -5
この例では、negateArray関数
で配列の各要素を負の値にしています。
ループを使った配列の更新
配列の要素を更新する際には、ループを使って効率的に操作することができます。
ループを使うことで、配列の全ての要素に対して同じ操作を簡単に適用できます。
#include <stdio.h>
// 配列の要素をインクリメントする関数
void incrementArray(int *array, int size) {
for (int i = 0; i < size; i++) {
array[i]++;
}
}
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int size = sizeof(numbers) / sizeof(numbers[0]);
// 配列のアドレスを渡して要素をインクリメントする
incrementArray(numbers, size);
// 結果を表示
for (int i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
return 0;
}
2 3 4 5 6
この例では、incrementArray関数
で配列の各要素を1ずつ増やしています。
配列の要素を変更する際の注意点
配列の要素を変更する際には、以下の点に注意が必要です。
- 配列の範囲を超えない: 配列の範囲外にアクセスすると、未定義の動作を引き起こす可能性があります。
- ポインタの正しい使用: ポインタを使う際には、正しいアドレスを指していることを確認する必要があります。
- 配列のサイズを確認: 配列のサイズを正しく把握し、ループの範囲を設定することが重要です。
これらの注意点を守ることで、安全に配列の要素を変更することができます。
応用例
配列の操作はC言語プログラミングにおいて非常に重要です。
ここでは、文字列配列の操作、多次元配列の書き換え、動的メモリ割り当て、配列のソートとフィルタリングについて解説します。
文字列配列の操作
文字列は文字の配列として扱われます。
文字列配列を操作することで、文字列の結合や変更が可能です。
#include <stdio.h>
#include <string.h>
// 文字列を大文字に変換する関数
void toUpperCase(char *str) {
for (int i = 0; str[i] != '\0'; i++) {
if (str[i] >= 'a' && str[i] <= 'z') {
str[i] = str[i] - ('a' - 'A');
}
}
}
int main() {
char greeting[] = "hello, world!";
// 文字列を大文字に変換
toUpperCase(greeting);
// 結果を表示
printf("%s\n", greeting);
return 0;
}
HELLO, WORLD!
この例では、toUpperCase関数
で文字列を大文字に変換しています。
多次元配列の書き換え
多次元配列は、行列のようにデータを格納するのに便利です。
多次元配列の要素を変更することで、データの操作が可能です。
#include <stdio.h>
// 行列の要素を2倍にする関数
void doubleMatrix(int matrix[2][3]) {
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
matrix[i][j] *= 2;
}
}
}
int main() {
int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
// 行列の要素を2倍にする
doubleMatrix(matrix);
// 結果を表示
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
return 0;
}
2 4 6
8 10 12
この例では、doubleMatrix関数
で多次元配列の各要素を2倍にしています。
配列の動的メモリ割り当て
動的メモリ割り当てを使うことで、実行時に配列のサイズを決定することができます。
malloc関数
を使ってメモリを確保し、free関数
で解放します。
#include <stdio.h>
#include <stdlib.h>
// 配列の要素を初期化する関数
void initializeArray(int *array, int size) {
for (int i = 0; i < size; i++) {
array[i] = i + 1;
}
}
int main() {
int size = 5;
int *numbers = (int *)malloc(size * sizeof(int));
if (numbers == NULL) {
printf("メモリの割り当てに失敗しました。\n");
return 1;
}
// 配列を初期化
initializeArray(numbers, size);
// 結果を表示
for (int i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
// メモリを解放
free(numbers);
return 0;
}
1 2 3 4 5
この例では、malloc
を使って動的にメモリを割り当て、initializeArray関数
で配列を初期化しています。
配列のソートとフィルタリング
配列のソートやフィルタリングは、データの整理や特定の条件に基づくデータの抽出に役立ちます。
#include <stdio.h>
#include <stdlib.h>
// 配列を昇順にソートする関数
int compare(const void *a, const void *b) {
return (*(int *)a - *(int *)b);
}
int main() {
int numbers[] = {5, 2, 9, 1, 5, 6};
int size = sizeof(numbers) / sizeof(numbers[0]);
// 配列をソート
qsort(numbers, size, sizeof(int), compare);
// 結果を表示
for (int i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
return 0;
}
1 2 5 5 6 9
この例では、qsort関数
を使って配列を昇順にソートしています。
compare関数
を使ってソートの基準を指定しています。
よくある質問
まとめ
配列を関数に渡して値を書き換える方法について、基本的な操作から応用例までを解説しました。
配列のアドレスを渡す方法や、ポインタを使った操作、多次元配列や動的メモリ割り当ての活用法を学びました。
これらの知識を活用して、より効率的なプログラムを作成してみてください。