ポインタ配列:複数の文字列をスマートに管理する

ポインタ配列とは、その名の通り、各要素がポインタである配列のことです。特に char* 型のポインタ配列は、複数の文字列をまとめて管理する際に非常に便利です。

通常の二次元配列 char str[4][20]; では、すべての要素が固定の長さ(この場合は20バイト)を確保してしまいますが、ポインタ配列を使えば、文字列の長さに応じて効率的にメモリを使用できます。


これは、配列の各要素が、メモリ上の別々の場所に格納されている文字列の**先頭アドレスを指している(ポイントしている)**イメージです。

ポインタ配列の使い方

char* の配列を定義し、各要素に文字列リテラルのアドレスを格納します。

#include <stdio.h>

int main(void) {
    // char* (文字列へのポインタ) を格納する配列を定義・初期化
    char* lang_list[4] = {
        "C",
        "Python",
        "JavaScript",
        "Rust"
    };

    printf("--- プログラミング言語リスト ---\n");
    printf("要素番号 | ポインタが指す文字列\n");
    printf("------------------------------------\n");

    for (int i = 0; i < 4; i++) {
        // lang_list[i] は、各文字列へのポインタ
        printf("  data[%d]  | %s\n", i, lang_list[i]);
    }
    
    // ポインタの値(アドレス)そのものを表示したい場合
    printf("\n--- ポインタ(アドレス)情報 ---\n");
    printf("要素番号 | 格納されているアドレス\n");
    printf("------------------------------------\n");
    for (int i = 0; i < 4; i++) {
        // %p はポインタ(アドレス)を表示するための書式指定子
        printf("  data[%d]  | %p\n", i, lang_list[i]);
    }

    return 0;
}

実行結果:

--- プログラミング言語リスト ---
要素番号 | ポインタが指す文字列
------------------------------------
  data[0]  | C
  data[1]  | Python
  data[2]  | JavaScript
  data[3]  | Rust

--- ポインタ(アドレス)情報 ---
要素番号 | 格納されているアドレス
------------------------------------
  data[0]  | 00403010
  data[1]  | 00403012
  data[2]  | 00403019
  data[3]  | 00403026

このように、lang_listという一つの配列変数を使って、長さの異なる複数の文字列を簡単に扱うことができます。


目次

関数ポインタ:関数を「変数」のように扱う

C言語では、変数だけでなく関数もメモリ上にアドレスを持っています。そして、その関数のアドレスを格納できる特殊なポインタが**「関数ポインタ」**です。

関数ポインタを使うと、関数をまるで変数のように扱えます。例えば、**状況に応じて呼び出す関数を切り替えたり、ある関数の引数として別の関数を渡したりする(コールバック)**といった高度なプログラミングが可能になります。

関数ポインタの使い方

関数ポインタの宣言は少し独特です。 戻り値の型 (*ポインタ名)(引数の型リスト);

サンプルコード: 2つの整数に対して、足し算を行う関数と引き算を行う関数を用意し、関数ポインタで切り替えて呼び出してみましょう。

#include <stdio.h>

// 関数のプロトタイプ宣言
int add(int a, int b);
int subtract(int a, int b);

int main(void) {
    int result;

    // 「int型の引数を2つ取り、int型の値を返す関数」を指すポインタを宣言
    int (*calculator_ptr)(int, int);

    // 1. 関数ポインタに add 関数のアドレスを代入
    calculator_ptr = add;
    // 関数ポインタ経由で add 関数を呼び出す
    result = calculator_ptr(10, 3);
    printf("add関数を呼び出した結果: %d\n", result);

    // 2. 関数ポインタに subtract 関数のアドレスを代入
    calculator_ptr = subtract;
    // 関数ポインタ経由で subtract 関数を呼び出す
    result = calculator_ptr(10, 3);
    printf("subtract関数を呼び出した結果: %d\n", result);
    
    // (*ポインタ名) という古い形式の呼び出し方も可能
    result = (*calculator_ptr)(10, 3);
    printf("古い形式での呼び出し結果: %d\n", result);


    return 0;
}

// 足し算を行う関数
int add(int a, int b) {
    return a + b;
}

// 引き算を行う関数
int subtract(int a, int b) {
    return a - b;
}

実行結果:

add関数を呼び出した結果: 13
subtract関数を呼び出した結果: 7
古い形式での呼び出し結果: 7

calculator_ptrという一つのポインタ変数が、状況に応じてadd関数を指したり、subtract関数を指したりと、その役割を変えているのが分かります。これにより、プログラムのロジックを動的に変更することが可能になります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次