[C言語] 配列のポインタに別の配列を代入できる?

C言語では、配列そのものを別の配列に直接代入することはできません。しかし、配列の先頭要素のアドレスを指すポインタを使用することで、配列の内容を操作することが可能です。

配列の名前はそのまま配列の先頭要素のアドレスを示すポインタとして扱われます。したがって、ポインタを使って別の配列の内容を参照したり、コピーしたりすることができます。

この方法を用いることで、配列の要素を効率的に操作することが可能です。

この記事でわかること
  • 配列のポインタを使って別の配列に代入する方法
  • 2次元配列のポインタ操作の実例
  • 関数への配列のポインタ渡しの方法
  • 動的配列とポインタを活用したメモリ管理
  • ポインタを使った配列のソートと文字列操作のテクニック

目次から探す

配列のポインタに別の配列を代入する方法

配列のポインタに別の配列を代入できるか

C言語では、配列そのものを別の配列に直接代入することはできません。

しかし、配列の先頭アドレスを指すポインタを使うことで、配列の内容を操作することが可能です。

ポインタを使うことで、配列の要素を間接的に操作したり、関数に配列を渡したりすることができます。

ポインタを使った配列の代入方法

配列のポインタを使って別の配列に代入するには、ポインタを利用して配列の要素を一つずつコピーする必要があります。

以下にその方法を示します。

#include <stdio.h>
int main() {
    // 元の配列
    int array1[] = {1, 2, 3, 4, 5};
    // コピー先の配列
    int array2[5];
    // ポインタを使って配列をコピー
    int *ptr1 = array1;
    int *ptr2 = array2;
    for (int i = 0; i < 5; i++) {
        *(ptr2 + i) = *(ptr1 + i);
    }
    // コピー結果を表示
    for (int i = 0; i < 5; i++) {
        printf("%d ", array2[i]);
    }
    return 0;
}
1 2 3 4 5

このコードでは、array1の要素をarray2にコピーしています。

ポインタを使うことで、配列の要素を一つずつ操作することが可能です。

配列のコピーとポインタの違い

配列のコピーとポインタを使った操作にはいくつかの違いがあります。

以下の表にその違いを示します。

スクロールできます
項目配列のコピーポインタを使った操作
メモリ使用新しいメモリ領域が必要既存のメモリ領域を使用
操作の柔軟性固定されたサイズの配列をコピー任意のサイズや部分的な操作が可能
パフォーマンス大きな配列では時間がかかることがあるポインタ操作は高速

ポインタを使った配列の操作例

ポインタを使うことで、配列の要素を動的に操作することができます。

以下に、ポインタを使った配列の操作例を示します。

#include <stdio.h>
void incrementArray(int *array, int size) {
    for (int i = 0; i < size; i++) {
        *(array + i) += 1; // 各要素を1増やす
    }
}
int main() {
    int numbers[] = {10, 20, 30, 40, 50};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    incrementArray(numbers, size);
    for (int i = 0; i < size; i++) {
        printf("%d ", numbers[i]);
    }
    return 0;
}
11 21 31 41 51

この例では、incrementArray関数を使って配列の各要素を1ずつ増やしています。

ポインタを使うことで、関数内で配列の要素を直接操作することができます。

配列のポインタを使った応用例

2次元配列のポインタ操作

2次元配列は、配列の配列として扱われます。

ポインタを使って2次元配列を操作することで、柔軟なデータ操作が可能です。

以下に2次元配列のポインタ操作の例を示します。

#include <stdio.h>
int main() {
    int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
    int (*ptr)[3] = matrix; // 2次元配列のポインタ
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%d ", ptr[i][j]);
        }
        printf("\n");
    }
    return 0;
}
1 2 3
4 5 6

このコードでは、2次元配列matrixの要素をポインタptrを使って出力しています。

関数への配列のポインタ渡し

配列を関数に渡す際、ポインタを使うことで配列の先頭アドレスを渡すことができます。

これにより、関数内で配列を操作することが可能です。

#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 data[] = {10, 20, 30, 40, 50};
    int size = sizeof(data) / sizeof(data[0]);
    printArray(data, size);
    return 0;
}
10 20 30 40 50

この例では、printArray関数に配列dataのポインタを渡し、関数内で配列の要素を出力しています。

動的配列とポインタの活用

動的配列は、実行時に必要なメモリを確保することで、柔軟にサイズを変更できます。

ポインタを使って動的配列を操作する方法を示します。

#include <stdio.h>
#include <stdlib.h>
int main() {
    int n = 5;
    int *dynamicArray = (int *)malloc(n * sizeof(int)); // メモリを動的に確保
    for (int i = 0; i < n; i++) {
        dynamicArray[i] = i * 10;
    }
    for (int i = 0; i < n; i++) {
        printf("%d ", dynamicArray[i]);
    }
    printf("\n");
    free(dynamicArray); // メモリを解放
    return 0;
}
0 10 20 30 40

このコードでは、mallocを使って動的にメモリを確保し、配列の要素を操作しています。

ポインタを使った配列のソート

ポインタを使って配列をソートすることも可能です。

以下に、バブルソートを用いた例を示します。

#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[] = {64, 34, 25, 12, 22, 11, 90};
    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;
}
11 12 22 25 34 64 90

この例では、bubbleSort関数を使って配列numbersを昇順にソートしています。

配列のポインタを使った文字列操作

文字列は文字の配列として扱われます。

ポインタを使って文字列を操作することで、文字列の内容を変更したり、表示したりすることができます。

#include <stdio.h>
void toUpperCase(char *str) {
    while (*str) {
        if (*str >= 'a' && *str <= 'z') {
            *str = *str - ('a' - 'A');
        }
        str++;
    }
}
int main() {
    char text[] = "hello, world!";
    toUpperCase(text);
    printf("%s\n", text);
    return 0;
}
HELLO, WORLD!

このコードでは、toUpperCase関数を使って文字列textを大文字に変換しています。

ポインタを使うことで、文字列の各文字を直接操作することができます。

よくある質問

配列のポインタとポインタ配列の違いは?

配列のポインタとポインタ配列は、似ているようで異なる概念です。

  • 配列のポインタ: 配列の先頭アドレスを指すポインタです。

例えば、int (*ptr)[10]は10個の整数を持つ配列を指すポインタです。

  • ポインタ配列: ポインタの配列です。

例えば、int *ptr[10]は10個の整数ポインタを持つ配列です。

これらは用途やメモリの扱い方が異なるため、目的に応じて使い分ける必要があります。

配列のポインタを使うメリットは?

配列のポインタを使うメリットは以下の通りです。

  • メモリ効率: 配列のポインタを使うことで、配列全体をコピーすることなく、メモリを効率的に使用できます。
  • 柔軟な操作: ポインタを使うことで、配列の要素を動的に操作したり、関数に渡したりすることが容易になります。
  • 関数間のデータ共有: 配列のポインタを使うことで、関数間で配列データを簡単に共有できます。

配列のポインタを使う際の注意点は?

配列のポインタを使う際には、以下の点に注意が必要です。

  • メモリ管理: 動的に確保したメモリは、使用後に必ずfree関数で解放する必要があります。

解放しないとメモリリークが発生します。

  • 境界チェック: 配列の範囲外にアクセスしないように注意が必要です。

範囲外アクセスは未定義動作を引き起こす可能性があります。

  • ポインタの初期化: ポインタを使用する前に必ず初期化することが重要です。

未初期化のポインタを使用すると、予期しない動作が発生することがあります。

まとめ

配列のポインタを使うことで、C言語における配列操作がより柔軟で効率的になります。

この記事では、配列のポインタの基本的な使い方から応用例までを解説しました。

これを機に、ポインタを活用したプログラミングに挑戦してみてください。

  • URLをコピーしました!
目次から探す