秘訣は、宣言を逆方向 (右から左) に読むことです:
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
const T
と T const
同一です。ポインター型の場合はさらに複雑になります:
const char*
定数 char
へのポインタです char const*
定数 char
へのポインタです char* const
(変更可能な) char
への定数ポインターです。
つまり、(1) と (2) は同じです。 (ポインティーではなく) ポインターを作成する唯一の方法 const
接尾辞-const
を使用することです .
これが、多くの人が常に const
を入れることを好む理由です。 型の右側 (「East const」スタイル):型に対する相対的な位置が一貫して覚えやすくなります (逸話的には、初心者に教えやすくなるようです)。
違いはありません。どちらも「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;
}