簡単な質問:
int testfunc1 (const int a)
{
return a;
}
int testfunc2 (int const a)
{
return a;
}
これらの2つの機能はすべての面で同じですか、それとも違いがありますか?私はC言語の答えに興味がありますが、C++言語に何か面白いことがあれば、私も知りたいです。
const T
およびT const
は同一です。ポインター型では、より複雑になります。
const char*
は、定数char
へのポインターです。char const*
は、定数char
へのポインターです。char* const
は(可変)char
への定数ポインターです。つまり、(1)と(2)は同じです。ポインターを(ポインティではなく)const
にする唯一の方法は、接尾辞const
を使用することです。
これが、多くの人がconst
を常にタイプの右側に配置することを好む理由です(「East const」スタイル)。初心者に簡単に教えることができます)。
コツは、宣言を逆方向(右から左)に読むことです:
const int a = 1; // read as "a is an integer which is constant"
int const a = 1; // read as "a is a constant integer"
両方とも同じものです。したがって:
a = 2; // Can't do because a is constant
逆読みのトリックは、次のようなより複雑な宣言を扱う場合に特に役立ちます。
const char *s; // read as "s is a pointer to a char that is constant"
char c;
char *const t = &c; // read as "t is a constant pointer to a char"
*s = 'A'; // Can't do because the char is constant
s++; // Can do because the pointer isn't constant
*t = 'A'; // Can do because the char isn't constant
t++; // Can't do because the pointer is constant
違いはありません。どちらも、「a」は変更できない整数であると宣言しています。
違いが現れるのは、ポインターを使用するときです。
これらの両方:
const int *a
int const *a
「a」を、変化しない整数へのポインタとして宣言します。 「a」は割り当てることができますが、「* a」は割り当てることができません。
int * const a
「a」が整数への定数ポインタであることを宣言します。 「* a」は割り当てることができますが、「a」は割り当てることができません。
const int * const a
「a」が定数整数への定数ポインタであることを宣言します。 「a」も「* a」も割り当てられません。
static int one = 1;
int testfunc3 (const int *a)
{
*a = 1; /* Error */
a = &one;
return *a;
}
int testfunc4 (int * const a)
{
*a = 1;
a = &one; /* Error */
return *a;
}
int testfunc5 (const int * const a)
{
*a = 1; /* Error */
a = &one; /* Error */
return *a;
}
Prakashは、宣言が同じであるということは正しいですが、ポインターのケースについてもう少し説明することが適切かもしれません。
「const int * p」は、そのポインターを使用してintを変更できないintへのポインターです。 「int * const p」は、別のintを指すように変更できないintへのポインターです。
http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.5 を参照してください。
const int
はint const
と同一です。Cのすべてのスカラー型で真です。一般に、Cの値渡しにより、スカラー関数パラメーターをconst
として宣言する必要はありません。セマンティクスとは、変数に対する変更は、それを囲む関数に対してローカルであることを意味します。
それらは同じですが、C++では常に右側でconstを使用する正当な理由があります。 constメンバー関数mustは次のように宣言されるため、どこでも一貫性が保たれます。
int getInt() const;
関数のthis
ポインターをFoo * const
からFoo const * const
に変更します。 こちらをご覧ください
これは直接的な答えではなく、関連するヒントです。物事を真っ直ぐにするために、私は常に対流「put const
on the outside」を使用します。「outside」とは、左端または右端を意味します。そうすれば混乱はありません-constは最も近いもの(型または*
)。例えば。、
int * const foo = ...; // Pointer cannot change, pointed to value can change
const int * bar = ...; // Pointer can change, pointed to value cannot change
int * baz = ...; // Pointer can change, pointed to value can change
const int * const qux = ...; // Pointer cannot change, pointed to value cannot change
はい、それらはint
だけで同じです
int*
この場合、それらは同じだと思いますが、順序が重要な例を次に示します。
const int* cantChangeTheData;
int* const cantChangeTheAddress;