回答:
違いはconst char *
、へのポインタでありconst char
、char * const
への定数ポインタchar
です。
最初に、ポイントされている値は変更できませんが、ポインターは変更できます。2番目に、ポイントされている値は変更できますが、ポインターは変更できません(参照と同様)。
もあります
const char * const
これは定数charへの定数ポインタです(そのため、変更はできません)。
注意:
次の2つの形式は同等です。
const char *
そして
char const *
これの正確な理由はC ++標準に記載されていますが、混乱を避けて注意することが重要です。私は好むいくつかのコーディング標準を知っています:
char const
以上
const char
(ポインタの有無にかかわらず)、const
要素の配置はポインタの場合と同じになりますconst
。
const int *foo,*bar;
の両方を宣言するだろうfoo
とbar
するint const *
が、int const *foo, *bar
宣言しfoo
するint const *
とbar
しますint *
。typedef int * intptr; const intptr foo,bar;
両方の変数をと宣言すると思いますint * const
。結合宣言を使用して、typedefなしでその型の2つの変数を作成する方法はわかりません。
I believe const int *foo,*bar; would declare both foo and bar to be int const *
:はい。but int const *foo, *bar would declare foo to be a int const * and bar to be int *
:いいえ!前のケースとまったく同じです。(fooとbarの両方で同じエラーが発生するideone.com/RsaB7nを参照してください)。I think typedef int * intptr; const intptr foo,bar; would declare both variables to be int * const
: はい。I don't know any way to use a combined declaration to create two variables of that type without a typedef
:まあ、int *const foo, *const bar;
。C宣言子の構文...
int const *foo, *volatile bar
に行いますかbar
?その両方作るconst
とvolatile
?I宣言した変数名とそのタイプのミスパスカルの明確な分離(整数へのポインタの配列へのポインタのようになりますvar foo: ^Array[3..4] of ^Integer
; `それはCでいくつかの面白いネストされた括弧付きのものになるだろう、私は思います。。
int const *foo, *volatile bar
"のタイプ部分はint const
(の前に停止*
)で、宣言子は*foo
(式*foo
はを示しますint const
)と*volatile bar
;です。読み取り右から左(のための良好なルールCV-修飾子)foo
へのポインタであるCONST INT、およびbar
れる揮発性へのポインタのconst int型(ポインタ自体が揮発性である、尖ったINTはCONST [としてアクセス]れます)。
[3..4]
な構文、その者は、10個の要素の配列を取りましょう): int *(*foo)[10];
。:それは表現としての(将来の)使用のミラー*(*foo)[i]
(とi
範囲内の整数[0, 10)
すなわち[0, 9]
)する最初の逆参照foo
の配列で取得するために、そしてインデックスにある要素にアクセスするi
(接尾ので、[]
接頭辞よりもバインドがタイト*
最後に、この要素を逆参照します、)を生成しますint
(ideone.com/jgjIjRを参照)。しかしtypedef
、それは簡単になります(ideone.com/O3wb7dを参照)。
混乱を避けるため、常にconst修飾子を追加してください。
int * mutable_pointer_to_mutable_int;
int const * mutable_pointer_to_constant_int;
int *const constant_pointer_to_mutable_int;
int const *const constant_pointer_to_constant_int;
p
タイプに関連していません:(const int *const)
。良くも悪くも(私に尋ねるとさらに悪いことですが)、CとC ++の両方のconst修飾子は、postfixを意味します:cf const member function void foo(int a) const;
。宣言する可能性const int
は、規則ではなく例外です。
const
常にその前にあるもの(その左側にあるもの)を変更します。それが型宣言の最初のものである場合を除いて、その後にあるもの(その右側にあるもの)を変更します。
したがって、これら2つは同じです。
int const *i1;
const int *i2;
それらはへのポインタを定義しますconst int
。場所i1
とi2
ポイントは変更できますが、ポイントする値は変更できません。
この:
int *const i3 = (int*) 0x12345678;
const
整数へのポインタを定義し、メモリ位置12345678を指すように初期化int
します。アドレス12345678で値を変更できますが、i3
指すアドレスを変更することはできません。
const * char
無効なCコードであり、無意味です。たぶん、あなたはa const char *
とa char const *
の違い、あるいはおそらくa とaの違いを尋ねるつもりでしconst char *
たchar * const
。
const char*
は定数文字へのポインタですは文字
char* const
へ
const char* const
の定数ポインタです定数文字への定数ポインタです
経験則:定義を右から左に読んでください!
const int *foo;
「は変更できないfoo
(*
)を指す()」を意味します。
プログラマにとって、これは「ポイントする値を変更しない」ことを意味します。int
const
foo
*foo = 123;
またはfoo[0] = 123;
無効になります。foo = &bar;
許可されている。int *const foo;
" foo
は変更できない(const
)ことを意味*
し、()はint
" を指します。
プログラマにとって、これは「参照するメモリアドレスを変更しない」ことをfoo
意味します。
*foo = 123;
またはfoo[0] = 123;
許可されています。foo = &bar;
無効になります。const int *const foo;
手段「foo
(変更できないconst
)と点(*
)にint
(変更できませんconst
)」。
プログラマにとって、これは「私が指すものの値foo
を変更したり、参照するアドレスを変更したりしないfoo
」ことを意味します。
*foo = 123;
またはfoo[0] = 123;
無効になります。foo = &bar;
無効になります。const char * xここで、Xは基本的に定数値を指す文字ポインターです
char * const xは定数である文字ポインターを参照しますが、それが指している位置は変更される可能性があります。
const char * const xは1と2の組み合わせであり、定数値を指す定数文字ポインターであることを意味します。
const * char xはコンパイラエラーを引き起こします。宣言できません。
char const * xはポイント1に等しい。
経験則として、constがvar nameを使用している場合、ポインターは一定ですが、ポインティング位置は変更できます。そうで、ポインターは一定のロケーションをポイントし、ポインターは別のロケーションをポイントできますが、ポインティングロケーションのコンテンツは変更できません。
多くの答えは、変数宣言のこの特定のインスタンスを理解するための特定のテクニック、経験則などを提供します。しかし、宣言を理解する一般的な手法があります。
時計回り/スパイラルルール
A)
const char *a;
時計回り/らせんのルールに従って、a
定数である文字へのポインターです。つまり、文字は一定ですが、ポインタは変わる可能性があります。つまりa = "other string";
、問題ありa[2] = 'c';
ませんが、コンパイルに失敗します
B)
char * const a;
ルールに従って、a
文字へのconstポインターです。つまり、あなたは行うことができますa[2] = 'c';
が、行うことはできませんa = "other string";
const char *およびchar * constを意味していると思います。
最初のconst char *は、定数文字へのポインターです。ポインタ自体は変更可能です。
2番目のchar * constは、文字への定数ポインターです。ポインタは変更できません。ポインタが指す文字は変更できます。
そして、ポインタと文字が変更できないconst char * constがあります。
ここにコード付きの詳細な説明があります
/*const char * p;
char * const p;
const char * const p;*/ // these are the three conditions,
// const char *p;const char * const p; pointer value cannot be changed
// char * const p; pointer address cannot be changed
// const char * const p; both cannot be changed.
#include<stdio.h>
/*int main()
{
const char * p; // value cannot be changed
char z;
//*p = 'c'; // this will not work
p = &z;
printf(" %c\n",*p);
return 0;
}*/
/*int main()
{
char * const p; // address cannot be changed
char z;
*p = 'c';
//p = &z; // this will not work
printf(" %c\n",*p);
return 0;
}*/
/*int main()
{
const char * const p; // both address and value cannot be changed
char z;
*p = 'c'; // this will not work
p = &z; // this will not work
printf(" %c\n",*p);
return 0;
}*/
// Some more complex constant variable/pointer declaration.
// Observing cases when we get error and warning would help
// understanding it better.
int main(void)
{
char ca1[10]= "aaaa"; // char array 1
char ca2[10]= "bbbb"; // char array 2
char *pca1= ca1;
char *pca2= ca2;
char const *ccs= pca1;
char * const csc= pca2;
ccs[1]='m'; // Bad - error: assignment of read-only location ‘*(ccs + 1u)’
ccs= csc; // Good
csc[1]='n'; // Good
csc= ccs; // Bad - error: assignment of read-only variable ‘csc’
char const **ccss= &ccs; // Good
char const **ccss1= &csc; // Bad - warning: initialization from incompatible pointer type
char * const *cscs= &csc; // Good
char * const *cscs1= &ccs; // Bad - warning: initialization from incompatible pointer type
char ** const cssc= &pca1; // Good
char ** const cssc1= &ccs; // Bad - warning: initialization from incompatible pointer type
char ** const cssc2= &csc; // Bad - warning: initialization discards ‘const’
// qualifier from pointer target type
*ccss[1]= 'x'; // Bad - error: assignment of read-only location ‘**(ccss + 8u)’
*ccss= ccs; // Good
*ccss= csc; // Good
ccss= ccss1; // Good
ccss= cscs; // Bad - warning: assignment from incompatible pointer type
*cscs[1]= 'y'; // Good
*cscs= ccs; // Bad - error: assignment of read-only location ‘*cscs’
*cscs= csc; // Bad - error: assignment of read-only location ‘*cscs’
cscs= cscs1; // Good
cscs= cssc; // Good
*cssc[1]= 'z'; // Good
*cssc= ccs; // Bad - warning: assignment discards ‘const’
// qualifier from pointer target type
*cssc= csc; // Good
*cssc= pca2; // Good
cssc= ccss; // Bad - error: assignment of read-only variable ‘cssc’
cssc= cscs; // Bad - error: assignment of read-only variable ‘cssc’
cssc= cssc1; // Bad - error: assignment of read-only variable ‘cssc’
}
構文:
datatype *const var;
char *const
この場合に該当します。
/*program to illustrate the behaviour of constant pointer */
#include<stdio.h>
int main(){
int a=10;
int *const ptr=&a;
*ptr=100;/* we can change the value of object but we cannot point it to another variable.suppose another variable int b=20; and ptr=&b; gives you error*/
printf("%d",*ptr);
return 0;
}
構文:
const datatype *var
または datatype const *var
const char*
この場合に該当します。
/* program to illustrate the behavior of pointer to a constant*/
#include<stdio.h>
int main(){
int a=10,b=20;
int const *ptr=&a;
printf("%d\n",*ptr);
/* *ptr=100 is not possible i.e we cannot change the value of the object pointed by the pointer*/
ptr=&b;
printf("%d",*ptr);
/*we can point it to another object*/
return 0;
}
の const
修飾子は、そのすぐ左の用語に適用されます。これの唯一の例外は、左側に何もない場合で、そのすぐ右側にあるものに適用されます。
これらはすべて、「定数への定数ポインタ」と同等の言い方ですchar
。
const char * const
const char const *
char const * const
char const const *
2つのルール
If const is between char and *, it will affect the left one.
If const is not between char and *, it will affect the nearest one.
例えば
char const *. This is a pointer points to a constant char.
char * const. This is a constant pointer points to a char.
int const *
(または const int *
)を使用することは、const int
変数を指すポインターではなく、この変数がconst
この特定のポインター用であることを指摘したいと思います。
例えば:
int var = 10;
int const * _p = &var;
上記のコードは完全に正常にコンパイルされます。それ自体は定数ではありませんが_p
、const
変数を指しますvar
。