検討:
int testfunc1 (const int a)
{
return a;
}
int testfunc2 (int const a)
{
return a;
}
これら2つの機能はすべての面で同じですか、それとも違いがありますか?
C言語の答えに興味がありますが、C ++言語で何か面白いことがあれば、それも知りたいです。
The trick is to read the declaration backwards (right-to-left):
const int a = 1; // read as "a is an integer which is constant"
int const a = 1; // read as "a is a constant integer"
Both are the same thing. Therefore:
a = 2; // Can't do because a is constant
The reading backwards trick especially comes in handy when you're dealing with more complex declarations such as:
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
const T
とT const
同一です。ポインタ型を使用すると、より複雑になります。
const char*
定数へのポインタですchar
char const*
定数へのポインタですchar
char* const
(可変)への定数ポインタですchar
つまり、(1)と(2)は同じです。(ポインタではなく)ポインタを作成する唯一の方法はconst
、接尾辞-を使用することですconst
。
これが、多くの人が常にタイプの右側に配置することを好む理由ですconst
(「Eastconst」スタイル)。これにより、タイプに対する相対的な位置が一貫し、覚えやすくなります(また、逸話的に、初心者に教えるのも簡単になるようです) )。
違いはありません。どちらも「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は、宣言が同じであるということは正しいですが、ポインターの場合についてもう少し説明する必要があるかもしれません。
「constint*p」は、intへのポインタであり、そのポインタを介してintを変更することはできません。「int*const p」は、別のintを指すように変更できないintへのポインタです。
https://isocpp.org/wiki/faq/const-correctness#const-ptr-vs-ptr-constを参照してください。
const int
int const
は、C のすべてのスカラー型で真であるように、 と同じです。一般に、スカラー関数パラメーターを宣言するconst
必要はありません。これは、C の値渡しセマンティクスが、変数へのすべての変更がその外側の関数に対してローカルであることを意味するためです。
それらは同じですが、C++ では常に右側に const を使用する正当な理由があります。const メンバー関数は次のように宣言する必要があるため、どこでも一貫性が保たれます。
int getInt() const;
this
関数内のポインターを からFoo * const
に変更しますFoo const * const
。こちらをご覧ください。
はい、彼らはただ同じですint
とは異なりますint*
これは直接的な答えではありませんが、関連するヒントです。物事をまっすぐにするために、私は常に「外側に置く」という対流を使用しますconst
。「外側」とは、左端または右端を意味します。そうすれば混乱はありません。 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
この場合、それらは同じだと思いますが、順序が重要な例を次に示します。
const int* cantChangeTheData;
int* const cantChangeTheAddress;