17

const関数にパラメータとして渡された配列にキーワードを追加する方法はありますか:

void foo(char arr_arg[])

( ) のconst前または ( ) の後charに配置すると、それは定数ではなく、.void foo(const char arr_arg[])charvoid foo(char const arr_arg[])chararr_arg

関数へのパラメーターとして送信される配列はポインターとして表されるためvoid foo(char arr_arg[])void foo(char* ptr_arg). それを考慮して、void foo(char * const ptr_arg)まさに私が達成したいものになるように関数を書き直すかもしれません。

constしかし、この宣言にキーワードを追加して、またはとvoid foo(char arr_arg[])同じにする方法があるかどうかを知りたいですか?void foo(char * const ptr_arg) void foo(char const * ptr_arg)void foo(const char * ptr_arg)

arr_arg配列表記で定数にする構文があるかどうかを理解したいだけです[]

4

5 に答える 5

20

const C ではの間に入れる必要が[]ありますが、準備ができていない人には奇妙に見えるかもしれません

void foo(char arr_arg[const]);

これは「新しい」C99 固有の構文です。C89/90 または C++ では、「配列」構文でそれを行う方法がないため、David の回答で示唆されているように、同等の「ポインター」構文に切り替える必要があります。

于 2012-06-06T20:24:30.627 に答える
10

最初に、特定の署名では、引数がコンパイラによってポインターに変換されるため、次のようになります。

void foo( char * arg );

現在、その署名で const にすることができる 2 つのエンティティがあります。ポインターとポイントされた型です。指す型を作るには、2 つの異なるが同等の方法で const にすることができます [*]:

void foo( const char * arg );
void foo( char const * arg );

ポインターは、次の構文で const にすることができます。

void foo( char * const arg );

ただし、関数シグネチャではchar arg[]、ポインタに変換されるのと同じ方法でchar *arg、最上位の修飾子が破棄されることに注意してください。したがって、宣言の観点からは、これら 2 つは同等です。

void foo( char * const arg );
void foo( char *       arg );

定義では、最上位の const を使用して、関数内で引数ポインターを (値によって) 変更しないようにコンパイラーに指示できます。ポインターを別の場所にリセットしようとすると、コンパイラーはそれを検出します。ただし、ポインターのみが const の場合、コンパイラーはポイントされたメモリーを喜んで変更させてくれます。関数で配列の内容を変更したくない場合は、最初の 2 つのシグネチャのいずれかを選択する必要があります。

[*] 型を読み取る一貫した方法を提供するため、私はこの形式を好む傾向がありchar const *ます。右から左に、 const char への非 const ポインターを読み取ります。さらに、(式で直接置換を実行することにより) typedef された型について推論する方が簡単です。与えられtypedef char* char_p;た 、const char_pおよびchar_p constは、 と同等であるchar * constと同時に異なりconst char *ます。一貫しconstて右側を使用することで、やみくもに typedef を置き換えて、理由を説明する必要なく型を読み取ることができます。

于 2012-06-06T20:23:48.807 に答える
2

はい、C では C99 以降で可能です:

void foo(char ptr_arg[const]);

有効な構文であり、と同等です

void foo(char *const ptr_arg);

より一般的に[]は、任意の型修飾子staticと整数式を含めることができます。しかし

オプションの型修飾子とキーワードstaticは、配列型を持つ関数パラメーターの宣言にのみ表示され、その後、最も外側の配列型の派生にのみ表示されます。

これは、ポインター宣言と同等の次元用です。

于 2012-06-06T20:29:11.753 に答える
0

C ++の場合、テンプレートを使用したMooingDuckの答えが最も簡単です。

C ++で実装されたCインターフェースを呼び出すCコードがある場合は、代わりに引数をポインター引数に変換し、それを作成することに固執します。const

C配列を直接使用する代わりに、Boostの配列を使用する場合はconst、テンプレート関数でもありますが、それを作成できます。

template <unsigned N>
void foo (Boost::array<char, N> const & arg) {}

利点はBoost::array、スタックからアレイを軽量に割り当てることができる一方で、コンテナ内の特性に依存するSTLアルゴリズムを完全に使用できることです。

于 2012-06-06T20:51:37.897 に答える