次の宣言の違いは何ですか?
char * const a;
const char * a;
違いを理解するために、この小さなプログラムを書きました。
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char **argv)
{
char a = 'x';
char b = 'y';
char * const pc1 = &a;
const char * pc2 = &a;
printf ("Before\n");
printf ("pc1=%p\n", pc1);
printf ("*pc1=%c\n", *pc1);
printf ("pc2=%p\n", pc2);
printf ("*pc2=%c\n", *pc2);
*pc1 = b;
/* pc1 = &b; */
/* *pc2 = b; */
pc2 = &b;
printf ("\n\n");
printf ("After\n");
printf ("pc1=%p\n", pc1);
printf ("*pc1=%c\n", *pc1);
printf ("pc2=%p\n", pc2);
printf ("*pc2=%c\n", *pc2);
return EXIT_SUCCESS;
}
プログラムを(gcc 3.4で)コンパイルして実行しました。出力は、違いをかなり強調しています。
Before
pc1=ffbfd7e7
*pc1=x
pc2=ffbfd7e7
*pc2=x
After
pc1=ffbfd7e7
*pc1=y
pc2=ffbfd7e6
*pc2=x
ただし、答えを得るには小さなプログラムを作成する必要がありました。マシンから離れている場合(たとえば、インタビューで)、質問に答えることができません。
上記の例をコメントして、誰かがconst
キーワードがどのように動作するか説明してください。
char * const a;
は、ポインターは定数で不変ですが、ポイントされたデータはそうではないことを意味します。
データ自体は定数ではないため、この場合、const_cast
(C++)またはcスタイルのキャストを使用して、constnessをキャストできます。
const char * a;
は、ポインタaを使用して、ポイントされたデータに書き込むことができないことを意味します。この場合、const_cast
(C++)またはcスタイルのキャストを使用してconstnessをキャストすると、ndefined Behaviorが発生します。
複雑な型を解析するには、変数から開始し、左に進み、外側に向かって螺旋を描きます。心配する配列や関数がない場合(変数名の右側にあるため)、これは右から左に読み取る場合になります。
したがって、char *const a;
にはa
があります。これはconst
へのchar
ポインター(*
)です。つまり、a
が指しているcharを変更できますが、a
が異なるものを指すようにすることはできません。
逆にconst char* b;
を使用すると、b
を持つchar
へのポインター(*
)であるconst
があります。 b
を任意のcharに向けることができますが、*b = ...;
を使用してそのcharの値を変更することはできません。
もちろん、一度に両方のconst-nessを同時に使用することもできます:const char *const c;
。
char * const a;
*a
は書き込み可能ですが、a
は書き込みできません。つまり、a
によって値pointedを変更できますが、a
自体は変更できません。 a
はchar
への定数ポインターです。
const char * a;
a
は書き込み可能ですが、*a
は書き込みできません。言い換えると、a
を変更(新しい場所を指す)ことができますが、値pointedをa
によって変更することはできません。
これは次と同じであることに注意してください
char const * a;
この場合、a
はconst char
へのポインターです。
これで、char * const a
とconst char * a
の違いがわかりました。定数ポインターまたは定数変数へのポインターである場合、多くの場合混乱します。
読み方は?以下の簡単な手順に従って、上の2つを識別します。
以下の宣言の読み方を見てみましょう
char * const a;
右から左に読む
ここで、a
で始まり、
1 a
の隣にconst
があります。
char * (const a)
;
--->したがって、a
はconstant
(????)
です。
2。今すぐあなたは*
を取得します
char (* (const a))
;
--->したがって、a
はconstant
pointer
から(????)
です。
3。一緒に行くとchar
があります
(char (* (const a)))
;
---> a
はconstant
pointer
からcharacter
変数です
a is constant pointer to character variable.
読みにくいですか?
同様に2番目の宣言について
const char * a;
もう一度a
から始めて、
1 a
に隣接して*
があります
--->したがって、a
は(????)へのpointer
です
2。今char
があります
--->したがって、a
はpointer
character
です。
まあそれは意味をなさない!!! pointer
とcharacter
をシャッフルする
--->したがって、a
はcharacter
pointer
から(?????)
です
3。これでconstant
ができました
--->したがってa
はcharacter
pointer
からconstant
変数です
しかし、宣言の意味を理解することはできますが、より賢明に聞こえるようにしましょう。
a is pointer to constant character variable
違いを理解する最も簡単な方法は、さまざまな可能性を考えることです。考慮する2つのオブジェクトがあります。ポインターと指すオブジェクトです(この場合、「a」はポインターの名前、指すオブジェクトは名前のないchar型です)。可能性は次のとおりです。
これらの異なる可能性は、次のようにCで表現できます。
これが可能な違いを説明することを願っています
最初はcharへの定数ポインターであり、2番目は定数charへのポインターです。コード内のすべてのケースに触れたわけではありません。
char * const pc1 = &a; /* You can't make pc1 point to anything else */
const char * pc2 = &a; /* You can't dereference pc2 to write. */
*pc1 = 'c' /* Legal. */
*pc2 = 'c' /* Illegal. */
pc1 = &b; /* Illegal, pc1 is a constant pointer. */
pc2 = &b; /* Legal, pc2 itself is not constant. */
上記は素晴らしい答えです。これを覚える簡単な方法を次に示します。
aはポインターです
* aは値です
「const a」と言うと、ポインターはconstです。 (つまり、char * const a;)
「const * a」と言うと、値はconstです。 (つまりconst char * a;)
最初に口頭で説明し、次に例を示します。
ポインターオブジェクトは、「const」ポインターまたは「const」オブジェクトへのポインター(またはその両方)として宣言できます。
A -const pointerは、最初に割り当てられたオブジェクトとは異なるオブジェクトを指すように再割り当てすることはできませんが、それが指すオブジェクト(「ポインティ」と呼ばれる)を変更するために使用できます。
参照変数は、したがって、「constpointers」の代替構文です。
一方、a const objectへのポインターは、同じ型または変換可能な型の別のオブジェクトを指すように再割り当てできますが、オブジェクトの変更には使用できません。
A constオブジェクトへのconstポインタも宣言することができ、指示先を変更したり、別のオブジェクトを指すように再割り当てしたりすることはできません。
例:
void Foo( int * ptr,
int const * ptrToConst,
int * const constPtr,
int const * const constPtrToConst )
{
*ptr = 0; // OK: modifies the "pointee" data
ptr = 0; // OK: modifies the pointer
*ptrToConst = 0; // Error! Cannot modify the "pointee" data
ptrToConst = 0; // OK: modifies the pointer
*constPtr = 0; // OK: modifies the "pointee" data
constPtr = 0; // Error! Cannot modify the pointer
*constPtrToConst = 0; // Error! Cannot modify the "pointee" data
constPtrToConst = 0; // Error! Cannot modify the pointer
}
お力になれて、嬉しいです!がんばろう!
https://cdecl.org/ のようなcdeclユーティリティまたはそのオンラインバージョンを使用できます。
例えば:
void (* x)(int (*[])());
はdeclare x as pointer to function (array of pointer to function returning int) returning void
です
簡単な方法で答えようとする:
char * const a; => a is (const) constant (*) pointer of type char {L <- R}. =>( Constant Pointer )
const char * a; => a is (*) pointer to char constant {L <- R}. =>( Pointer to Constant)
定数ポインター:
ポインターは定数です!!。つまり、保持しているアドレスは変更できません。読み取り専用メモリに保存されます。
もっと理解するために、ポインターのアドレスを変更してみましょう。
char * const a = &b;
char c;
a = &c; // illegal , you can't change the address. `a` is const at L-value, so can't change. `a` is read-only variable.
定数ポインターが何かを指すと、それは永遠に続くことを意味します。
ポインターa
はb
のみを指します。
ただし、b
の値は変更できます。例:
char b='a';
char * const a =&b;
printf("\n print a : [%c]\n",*a);
*a = 'c';
printf("\n now print a : [%c]\n",*a);
定数へのポインター:
ポインターが指す値は変更できません。
const char *a;
char b = 'b';
const char * a =&b;
char c;
a=&c; //legal
*a = 'c'; // illegal , *a is pointer to constant can't change!.
const char * a;
これは、定数文字へのポインターを示します。例えば.
char b='s';
const char *a = &b;
ここでa
は定数char( 's'、この場合)を指します。a
を使用してその値を変更することはできません。ただし、この宣言は、それが指す値が constant、それは、a
に関する限り、値が定数であることを意味します。 b
の値を変更すると、b
の値を直接変更できますが、a
ポインターを介して間接的に値を変更することはできません。
*a='t'; //INVALID b='t' ; //VALID
char * const a=&b
これは、charへの定数ポインターを示します。 a
がb
のみを指すように制限しますが、b
の値を変更できます。
それが役に立てば幸い!!! :)