C言語

【C言語】第4章第13回:ポインタ配列の活用方法

ポインタ配列は、効率的なデータの操作や管理を可能にする強力なツールです。この章では、ポインタ配列の基本的な概念から高度な応用例までを詳しく解説します。

1. ポインタ配列の基本概念

1.1 ポインタ配列とは?

ポインタ配列は、ポインタの集合体として機能します。通常の配列がデータ型の値を格納するのに対して、ポインタ配列はメモリアドレスを格納します。

  • 例:整数型ポインタの配列int *arr[10];
  • それぞれの要素は、整数型変数を指すポインタです。

ポインタ配列の主な用途:

  • 文字列配列の管理
  • 多次元配列の操作
  • 関数ポインタの管理

1.2 メモリモデルを理解する

ポインタ配列の理解には、メモリモデルを視覚化することが役立ちます。例えば、int *arr[3]の場合:

  • arrは配列の先頭アドレスを指します。
  • 各要素は整数型変数を指すポインタです。

例:ポインタ配列の基本操作

#include <stdio.h>

int main() {
    int a = 10, b = 20, c = 30;
    int *arr[3] = {&a, &b, &c};

    for (int i = 0; i < 3; i++) {
        printf("Value at arr[%d]: %d\n", i, *arr[i]);
    }

    return 0;
}

この例では、arrの各要素がそれぞれ異なる整数を指します。

2. ポインタ配列の基本的な使い方

2.1 文字列配列の操作

ポインタ配列は文字列の管理によく使用されます。

例:文字列の配列をポインタで操作

#include <stdio.h>

int main() {
    const char *words[] = {"Apple", "Banana", "Cherry"};
    int size = sizeof(words) / sizeof(words[0]);

    for (int i = 0; i < size; i++) {
        printf("Word[%d]: %s\n", i, words[i]);
    }

    return 0;
}

この例では、各ポインタが文字列リテラルを指します。

2.2 関数ポインタ配列の使用

関数ポインタ配列を使えば、複数の関数を柔軟に呼び出すことができます。

例:関数ポインタ配列の活用

#include <stdio.h>

int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }

int main() {
    int (*operations[])(int, int) = {add, subtract, multiply};
    int a = 10, b = 5;

    for (int i = 0; i < 3; i++) {
        printf("Result: %d\n", operations[i](a, b));
    }

    return 0;
}

3. 応用例:ポインタ配列を使った動的メモリ管理

3.1 動的に割り当てられた配列の管理

ポインタ配列を使えば、動的に確保した複数のメモリブロックを効率的に管理できます。

例:動的メモリ管理

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *arr[3];

    for (int i = 0; i < 3; i++) {
        arr[i] = (int *)malloc(5 * sizeof(int));
        for (int j = 0; j < 5; j++) {
            arr[i][j] = i * 5 + j;
        }
    }

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 5; j++) {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }

    for (int i = 0; i < 3; i++) {
        free(arr[i]);
    }

    return 0;
}

4. 練習問題

以下の課題に挑戦して、ポインタ配列の使い方を実践的に学びましょう。

  1. 文字列の配列をポインタ配列で管理し、すべての文字列を逆順に出力するプログラムを作成してください。
  2. 関数ポインタ配列を使用して、動的に異なる計算を呼び出すメニューシステムを作成してください。
  3. ポインタ配列を使って、複数の動的に割り当てられた整数配列を管理し、各配列の平均を計算するプログラムを作成してください。

5. 練習問題の解答と解説

問1の解答

#include <stdio.h>
#include <string.h>

int main() {
    const char *words[] = {"Apple", "Banana", "Cherry"};
    int size = sizeof(words) / sizeof(words[0]);

    for (int i = 0; i < size; i++) {
        const char *word = words[i];
        for (int j = strlen(word) - 1; j >= 0; j--) {
            printf("%c", word[j]);
        }
        printf("\n");
    }

    return 0;
}

6. まとめ

ポインタ配列は、柔軟性と効率性を備えた強力なツールです。基本的な操作から高度な応用までを学び、実際のプログラムで活用してみてください。