const char *とcharconst *-それらは同じですか?


81

私の理解では、const修飾子は右から左に読む必要があります。それから、私はそれを得る:

const char*

char要素を変更できないポインタですが、ポインタ自体は変更できます。

char const*

mutablecharsへの定数ポインタです。

しかし、次のコードで次のエラーが発生します。

const char* x = new char[20];
x = new char[30];   //this works, as expected
x[0] = 'a';         //gives an error as expected

char const* y = new char[20];
y = new char[20];   //this works, although the pointer should be const (right?)
y[0] = 'a';         //this doesn't although I expect it to work

それで...それはどれですか?私の理解または私のコンパイラ(VS 2005)は間違っていますか?


35
疑わしい場合は、常にスパイラルルールを使用してください。
Alok Save

「...そのchar要素は変更できますが、ポインタ自体は変更できます...」 —これらの「できる」の1つに対して「できない」と言うつもりだったと思いますが、方法がわかりませんあなたが混乱しているので、どちらを修正すればよいかわかりません:P
2011

1
このウェブサイトをお試しください:www.cdecl.org
yasouser 2011

コンパイラは決して間違っていません;)
モノリス

回答:


129

実際には、標準に従ってconst、要素をその左側に直接変更します。const宣言の先頭での使用は、便利なメンタルショートカットです。したがって、次の2つのステートメントは同等です。

char const * pointerToConstantContent1;
const char * pointerToConstantContent2;

ポインタ自体が変更されていないことを確認するにはconst、アスタリスクの後に配置する必要があります。

char * const constantPointerToMutableContent;

ポインターとそれが指すコンテンツの両方を保護するには、2つのconstを使用します。

char const * const constantPointerToConstantContent;

個人的には、変更したくない部分の後に常にconstを付けて、ポインタが一定にしておきたい部分でも一貫性を保つようにしています。


23
「便利な速記」は、短くなく、通常の規則に従わないものの興味深い説明です。
beetstra 2011

標準では、どの順序を使用するかは実際には関係ありません。セクション7.1.6は両方の場所を示しており、1つだけで使用すると述べています。
edA-qa mort-ora-y 2011

1
@beetstra同意します。もう少しわかりやすくするために、「便利なメンタルショートカット」に変更しました。
グレイソン2012年

31

両方が同じであるため、機能します。これで混乱するかもしれませんが、

const char*  // both are same
char const*

そして

char* const  // unmutable pointer to "char"

そして

const char* const  // unmutable pointer to "const char"

[これを覚えておくために、ここに簡単なルールがあります。「*」は最初にLHS全体に影響します]


はい、わかりました。どうもありがとう。
Luchian Grigore 2011

1
unmutable pointer to char*.ITはを指すポインタであるunmutablecharありませんchar *
Alok Save

25

これは、ルールが次のとおりであるためです。

ルール:const左側に何もない場合を除いて、左側にバインドし、次に右側にバインドします:)

したがって、これらを次のように見てください。

(const --->> char)*
(char <<--- const)*

どちらも同じです!ああ、--->>そして<<---事業者ではありません、彼らは何を示しているconstに特異的に結合します。


2
ええ、正しい演算子はで-->>あり、値に対してのみ動作します。試してみてくださいint i = 8; std::cout << (i -->> 1) << std::endl;:)
Alexander Malakhov 2011

11

2つの単純な変数初期化の質問から

に関する本当に良い経験則const

宣言を右から左に読む。

(Vandevoorde / Josutissの「C ++テンプレート:完全ガイド」を参照)

例えば:

int const x; // x is a constant int
const int x; // x is an int which is const

// easy. the rule becomes really useful in the following:
int const * const p; // p is const-pointer to const-int
int const &p;        // p is a reference to const-int
int * const * p;     // p is a pointer to const-pointer to int.

私はこの経験則に従っているので、そのような宣言を二度と誤解することはありませんでした。

(:sisab retcarahc-rep a no ton、sisab nekot-rep a no tfel-ot-thgir naem I hguohT:tidE


+1これは素晴らしいです、ありがとう!私は何年もの間のようなものに頭を悩ませようとしてきましたconst char* const、そしてあなたのおかげで私は今それを手に入れました。
OMGtechy 2014

5

これが私がいつも解釈しようとする方法です:

char *p

     |_____ start from the asterisk. The above declaration is read as: "content of `p` is a `char`".

char * const p

     |_____ again start from the asterisk. "content of constant (since we have the `const` 
            modifier in the front) `p` is a `char`".

char const *p

           |_____ again start from the asterisk. "content of `p` is a constant `char`".

それが役に立てば幸い!


0

どちらの場合も、定数文字を指しています。

const char * x  //(1) a variable pointer to a constant char
char const * x  //(2) a variable pointer to a constant char
char * const x  //(3) a constant pointer to a variable char
char const * const x //(4) a constant pointer to a constant char
char const * const * x //(5) a variable pointer to a constant pointer to a constant char
char const * const * const x //(6) can you guess this one?

デフォルトconstでは、左にあるものに適用されますが、(1)のように、前に何もない場合は、右にあるものに適用できます。


最後の1つ:定数ポインター、定数ポインター、定数文字への定数変数ポインター。
Secko

「定数変数ポインタ」が「定数ポインタ」を意味する場合、あなたはそれを仲間に釘付けにしました!
LinoMediavilla19年

(5)では、識別子「x」の前の最後のアスタリスクの右側に「const」がないという理由だけで、定数charへの定数ポインタへの変数ポインタです。しかし、それが定数ポインタになる(6)では、残りは同じままです。
LinoMediavilla19年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.