2012-02-23 22 views
4

最近、関数の仮引数を変更する必要があるコードをいくつか調整しました。もともと、パラメータは次のようなものでした。(ノート、構造が先にtypedefされました):constへのポインタまたはconstへのconstポインタを仮パラメータとして宣言する

static MySpecialStructure my_special_structure; 
static unsigned char char_being_passed;    // Passed to function elsewhere. 
static MySpecialStructure * p_my_special_structure; // Passed to function elsewhere. 

int myFunction (MySpecialStructure * p_structure, unsigned char useful_char) 
{ 
    ... 
} 

私は前にmy_special_structureを定義し、初期化する可能性があるため、変更が行われた時間とのMyFunctionをコンパイルし、それの値を変更したことがありません。これは、次のように変更につながった:

static const MySpecialStructure my_special_structure; 
static unsigned char char_being_passed;    // Passed to function elsewhere. 
static MySpecialStructure * p_my_special_structure; // Passed to function elsewhere. 

int myFunction (const MySpecialStructure * p_structure, unsigned char useful_char) 
{ 
    ... 
} 

は、私はまた私があったことを私のプログラムにリントを実行したときに、いくつかの情報818のは、さまざまな機能の数を参照することに気づきました。情報には"Pointer parameter 'x'(行253)がconst" "を指すと宣言できます。

今、私は上記に関して2つの質問があります。まず、上記のコードに関しては、関数内でポインタも変数MySpecialStructure内の変数も変更されていないので、ポインタを定数として宣言すると有益でしょうか?例えば -

int myFunction (const MySpecialStructure * const p_structure, unsigned char useful_char) 

私の2番目の質問は、リントの情報です。関数がその値を変更していない場合にポインタを定数仮パラメータとして宣言することには利点や欠点がありますか?関数に渡すものが決して定数として宣言されていない場合でもですか?例えば -

static unsigned char my_char; 
static unsigned char * p_my_char; 
p_my_char = &my_char; 

int myFunction (const unsigned char * p_char) 
{ 
    ... 
} 

ありがとうございました!

明確化のために編集 -

どのようなものがありconstからconstまたはconstポインタへのポインタ宣言の利点 - 仮パラメータとしてを?私は私がができることを知っていますしかし、なぜ私はしたいでしょう...特にポインタが渡され、それが指しているデータが定数宣言されていない場合?

答えて

7

仮引数としてポインタをconstとして宣言することの利点は何ですか?私はそれを行うことができることを知っていますが、なぜ私は...特にポインターが渡され、ポインターが指しているデータが定数宣言されていない場合には?

constへのポインタを意味するものとします。

constへのポインタをパラメータとして持つことにより、プログラマに関数がポインターが指すオブジェクトを変更しないことを伝えることによって、APIを文書化することの利点があります。例えば

memcpyプロトタイプを見て:

void *memcpy(void * restrict s1, const void * restrict s2, size_t n); 

それは、オブジェクトがs2によって指さプログラマがmemcpy呼び出しによって変更されることはありません伝えます。

ポインターからポインターを変更してconstにすると、実装が診断を発行するため、コンパイラーが強制的に文書化します。

+0

私は 'const'へのポインタを意味しました、ありがとう...私はもっと混乱を追加するために明確にしようとすると嫌いです。 –

2

あなたの最初の質問では、ポインタまたはそれが指している変数のいずれかを変更しないことを確信しているなら、是非、それらを両方とも一定にすることができます!

渡されたポインタが定数ではないにもかかわらず、仮ポインタパラメータがconstとして宣言されている理由については、通常のユースケースはライブラリ関数printf()です。 printfconst char *を受け入れますが、char*を渡してもコンパイラはそれを受け付けません。このような場合、printf()は、間違って作成されてしまい、意図せずにユーザーのデータを変更することはありません。そのようなprintf()明らかにあなたがconst char *またはchar*を渡すかどうか、心配しないでください、私はまだあなたのデータを変更しません!

第2の質問のために、constポインタは、一般にメモリアドレスに直接書き込む埋め込み型の世界で優れたアプリケーションを見つけます。Hereの詳細な説明

+0

私は私の質問にちょっとした言葉を書かねばならないと思います...ポインタをconst **として仮引数として宣言することの利点は何ですか?私はそれを行うことができることを知っていますが、なぜ私は...特にポインターが渡され、それが指しているデータが定数宣言されていない場合には? –

+0

私は自分の答えを更新しました! –

3

仮パラメータをconstと宣言すると、コンパイラは、コードがそのパラメータを変更しようとしていないことを確認し、ソフトウェアの品質を向上させることができます。

3

constはまた、あなたがそうしないためのオプションを持っていながら、まあ、constとして何かを宣言することの利点何あなたが彼らの背中

1

の後ろには、このパラメータを変更することはありませんあなたの機能をユーザーに示すことができます?結局のところ、あなたがそれに触れなければ、それはconstかどうかは関係ありません。これは、コンパイラがあなたのためにできるいくつかの安全性チェックを提供し、関数インタフェースの情報を提供します。たとえば、文字列リテラルをconst char *が必要な関数に渡すことはできますが、パラメータがchar *と宣言されている場合は注意が必要です。

2

Const正確さは素晴らしいことです。 1つは、コンパイラが間違いを防ぐのを助けることです。明らかな単純なケースは、比較するときに割り当てることです。その場合、ポインタがconstの場合、コンパイラはエラーを返します。 Google 'const correctness'であり、その利点については多くのリソースがあります。

関連する問題