1. ホーム
  2. c

[解決済み] C 言語のポインタ:固定サイズの配列へのポインティング

2022-05-15 21:40:25

質問

この質問は、C言語の達人たちに送るものです。

C言語では、次のようにポインタを宣言することが可能です。

char (* p)[10];

...これは基本的にこのポインタが10文字からなる配列を指していることを表しています。このようにポインタを宣言すると、異なるサイズの配列のポインタをpに代入しようとすると、コンパイル時にエラーが発生します。また、単純なcharポインタの値をpに代入しようとすると、コンパイル時にエラーが発生します。

このようにポインタを宣言することは、特に関数にポインタを渡すときに、非常に便利であるように見えます。通常、人々はそのような関数のプロトタイプをこのように書くでしょう。

void foo(char * p, int plen);

もし特定のサイズのバッファを期待していたのであれば、単純にplenの値をテストするでしょう。しかし、pを渡した人が本当にそのバッファの有効なメモリ位置plenを与えるかどうかは保証できません。この関数を呼び出した人が正しいことをやっていると信じるしかないのです。一方

void foo(char (*p)[10]);

...は、呼び出し元が指定されたサイズのバッファを与えるよう強制します。

これは非常に便利なように見えますが、私が今まで遭遇したどのコードでも、このように宣言されたポインタを見たことがありません。

私の質問は、人々がこのようにポインタを宣言しない理由があるのでしょうか?私は何か明らかな落とし穴を見ていないのでしょうか。

どのように解決するのですか?

AndreyTの回答に補足します(このトピックに関する詳細情報を探してこのページにたどり着いた人がいるかもしれないので)。

これらの宣言でもっと遊ぶようになると、C ではこの宣言に大きなハンディキャップがあることに気づきます (C++ ではないようです)。自分が書き込んだバッファへの const ポインターを呼び出し元に与えたいという状況は、かなり一般的です。つまり、Cの標準(6.7.3 - パラグラフ8)はこのようなものと矛盾しているのです。


   int array[9];

   const int (* p2)[9] = &array;  /* Not legal unless array is const as well */

この制約はC++にはないようで、この種の宣言ははるかに有用です。しかし C の場合、固定サイズのバッファへの const ポインタが必要なときはいつでも、通常のポインタ宣言に戻る必要があります (バッファ自体がそもそも const 宣言されている場合は別ですが)。より詳しい情報はこのメールスレッドで見ることができます。 リンクテキスト

もうひとつは、AndreyTが指摘したように、ほとんどの人はこのようにポインタを宣言できることさえ知らないという事実です。