考慮してください:
int testfunc1 (const int a)
{
return a;
}
int testfunc2 (int const a)
{
return a;
}
これら2つの機能はすべての面で同じですか、それとも違いがありますか?
C言語の答えに興味がありますが、C ++言語に何か面白いものがあったら知りたいです。
考慮してください:
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
char const *
、左から右に読むと、「pointer、const、char」です。これはconst charへのポインタです。「定数のポインター」と言うと、「定数」の形容詞はポインターの上にあります。したがって、その場合、形容詞のリストは「const、pointer、char」である必要があります。しかし、あなたの言う通り、このトリックにはあいまいさがあります。これは実際には「トリック」であり、決定的な「ルール」ではありません。
違いはありません。どちらも「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へのポインターです。
https://isocpp.org/wiki/faq/const-correctness#const-ptr-vs-ptr-constを参照してください。
これは直接的な答えではなく、関連するヒントです。物事をまっすぐにするために、私は常に「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
それらは同じですが、C ++では常に右側でconstを使用するのに十分な理由があります。constメンバー関数は次のように宣言する必要があるため、どこでも一貫性があります。
int getInt() const;
これは、変更this
から関数内のポインタをFoo * const
しますFoo const * const
。こちらをご覧ください。
この場合は同じだと思いますが、順序が重要な例を次に示します。
const int* cantChangeTheData;
int* const cantChangeTheAddress;