第10章の4 ポインタのポインタ

1. 「ポインタの配列」と「ポインタのポインタ」

前節で学習した「ポインタの配列」はポインタを使ってアクセスすることができます。 このポインタを「ポインタのポインタ」と呼びます。

#include <stdio.h>

int main(void)
{
    char *mnthp[3] = {                  // ポインタの配列の宣言
        "January", "February", "March"
    };
    char **p1, **p2, **p3;             // 「ポインタのポインタ」の宣言
    p1 = p2 = p3 = mnthp;              // 「ポインタのポインタ」にポインタの配列
                                       // の先頭番地を設定

    // 例1
    printf("** 例1の出力 **\n");
    for (int i = 0; i < 3; i++) {      // 「ポインタのポインタ」の値を変えずに
        printf("%s\n", *(p1 + i));     // 相対的に文字列を出力
    }

    // 例2
    printf("\n** 例2の出力 **\n");
    for (int i = 0; i < 3; i++) {      // 「ポインタのポインタ」の値そのものを
        printf("%s\n", *p2);           // 更新して絶対的に文字列を出力
        ++p2;
    }

    // 例3
    printf("\n** 例3の出力 **\n");
    for (int i = 0; i < 3; i++) {
        int j = 0;
        while(*(*p3 + j) != '\0') {     // 「ポインタのポインタ」を使って、
            printf("%c", *(*p3 + j));   // 1文字ずつ出力する
            j++;
        }
        printf("\n");
        ++p3;
    }

    return 0;
}

【実行結果例】
** 例1の出力 **
January
February
March

** 例2の出力 **
January
February
March

** 例3の出力 **
January
February
March

【例1と例2の解説図】

【例3の解説図】

〇 演習問題

“Iizumi”,”Kanto”,”Kudo”,”Sato”,”Sugawara”,”Matuda”,”Wada”の7個の文字列の長さを求めて表示しなさい。
ただし、ポインタのポインタを用いること。

【実行結果例】
6文字 : Iizumi
5文字 : Kanto
4文字 : Kudo
4文字 : Sato
8文字 : Sugawara
6文字 : Matuda
4文字 : Wada

解答例

// 解答例1
#include <stdio.h>

int main(void)
{
    char *name[7] = {
        "Iizumi", "Kanto", "Kudo", "Sato", 
        "Sugawara", "Matuda", "Wada"
    };
    char **p;
    int count;

    p = name;
    for (int i = 0; i < 7; i++){
        for (count = 0; *(*(p + i) + count) != '\0'; count++);
        printf("%2d文字 : %s\n", count, *(p+i));
    }

    return 0;
}
// 解答例2
#include <stdio.h>

int main(void)
{
    char *name[7] = {
        "Iizumi", "Kanto", "Kudo", "Sato", 
        "Sugawara", "Matuda", "Wada"
    };
    char **p;
    int count;

    p = name;
    for (int i = 0; i < 7; i++){
        for (count = 0; *(*p + count) != '\0'; count++);
        printf("%2d文字 : %s\n", count, *p);
        ++p;
    }
    return 0;
}
// 解答例3
#include <stdio.h>
#include <string.h>

int main(void)
{
    char *name[7] = {
        "Iizumi", "Kanto", "Kudo", "Sato", 
        "Sugawara", "Matuda", "Wada"
    };
    char **p;

    p = name;
    for (int i = 0; i < 7; i++) {
        printf("%2d文字 : %s\n", strlen(*p), *p);
        ++p;
    }

    return 0;
}
  • 解答例1 は、p = name; のままにしておき、ループ内で (p + i) と 二重のポインタ演算((*(p+i) + count))を使って文字を数えます。
  • 解答例2 は、ループごとに p 自身を ++p で インクリメント し、内側のループでは常に *p(現ポインタ先)のみを走査します。
  • 解答例3 は手作業のカウントループを省き、標準ライブラリの strlen(*p) で文字数を取得し、やはり ++p で次の文字列へ移動します。

コメント