152

次の宣言の違いは何ですか?

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上記の例にコメントして、キーワードがどのように機能するかを誰か説明してもらえますか?

4

11 に答える 11

189
char * const a;

ポインターは一定で不変ですが、ポイントされたデータはそうではありません。この場合、データ自体は定数ではないため、(C++ の場合) または c スタイルのキャストを
使用して constness をキャストできます。const_cast

const char * a;

ポインター a を使用して、ポイントされたデータに書き込むことができないことを意味します。この場合、const_cast(C++) または c スタイルのキャストを使用して constness をキャストすると、Undefined Behaviorが発生します。

于 2012-04-10T15:39:53.797 に答える
104

複雑な型を解析するには、変数から開始し、左に進み、外側に向かってスパイラルします。心配する配列や関数がない場合 (これらは変数名の右側にあるため)、これは右から左への読み取りのケースになります。

これchar *const a;はへaconstポインタ ( *)charです。言い換えれば、指している文字を変更することはできますが、別のものaを指し示すことはできませんa

逆に、const char* b;you havebは へのポインタ ( *)charですconst。任意の文字を指定できbますが、 を使用してその文字の値を変更することはできません*b = ...;

もちろん、const-ness の両方のフレーバーを一度に持つこともできますconst char *const c;

于 2014-05-20T09:11:11.037 に答える
65
char * const a;

*a書き込み可能ですが、そうでaはありません。つまり、が指す値を変更することはできますが、それ自体aを変更することはできませんaaへの定数ポインタcharです。

const char * a; 

a書き込み可能ですが、そうで*aはありません。つまり、変更a(新しい場所を指す)はできますが、が指す値を変更することはできませa

これはと同じであることに注意してください

char const * a;

この場合、aはへのポインタconst charです。

于 2012-04-10T16:01:52.107 に答える
27

char * const aとの違いがわかったのでconst char * a、多くの場合、定数ポインターまたは定数変数へのポインターである場合、混乱します。

読み方は?以下の簡単な手順に従って、上位 2 つを識別します。

以下の宣言の読み方を見てみましょう

char * const a;

右から左に読む

ではa

1. 隣接してaありますconst

char * (const a);

---> もそうaですconstant (????)

2. 今、あなたが得るに沿って行きます*

文字(* (const a));

---> to もそうaです。constant pointer(????)

3. 行くとそこにあるchar

(char (* (const a)));

--- > toa変数constant pointercharacter

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 pointerconstant

しかし、宣言が何を意味するかは理解できますが、もっと賢明に聞こえるようにしましょう。

a is pointer to constant character variable
于 2014-07-05T07:38:08.587 に答える
12

1 つ目は 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. */
于 2012-04-10T15:39:57.120 に答える
6

最初に口頭で説明し、次に例を挙げて説明します。

ポインター オブジェクトは、const ポインターまたは const オブジェクトへのポインター (またはその両方) として宣言できます。

const ポインターは、最初に割り当てられたオブジェクトとは異なるオブジェクトを指すように再割り当てする ことはできませんが、それが指すオブジェクト (「ポインティー」と呼ばれます) を変更するために使用できます。
したがって、参照変数は constpointers の代替構文です。

一方、 const オブジェクトへのポインターは、同じ型または変換可能な型の別のオブジェクトを指すように再割り当てできますが、オブジェクトの変更には使用できません。

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 
}

お力になれて、嬉しいです!幸運を!

于 2015-08-03T12:14:06.203 に答える
5

上記は素晴らしい答えです。これを覚える簡単な方法は次のとおりです。

a はポインタです

*a は値です

「const a」と言うと、ポインターは const になります。(つまり、char * const a;)

「const *a」と言うと、値は const になります。(つまり、const char * a;)

于 2014-12-25T15:08:20.963 に答える
2

https://cdecl.org/のような cdecl ユーティリティまたはそのオンライン バージョンを使用できます。

例えば:

void (* x)(int (*[])()); です declare x as pointer to function (array of pointer to function returning int) returning void

于 2015-02-03T14:54:24.950 に答える
1

簡単な方法で答えようとしています:

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!.
于 2015-02-07T08:24:34.370 に答える
0
const char * a;

これは、定数文字へのポインタを示します。たとえば。

char b='s';
const char *a = &b;

ここでa は、定数 char('s', この場合)aを指します。その値を変更するために使用することはできません。しかし、この宣言は、それが指す値が実際に定数であることを意味しません。値がに関する限り、一定aです。の値を変更することで の値をb直接変更できますが、ポインターbを介して間接的に値を変更することはできません。a

*a='t'; //INVALID b='t' ; //VALID

char * const a=&b

これは、char への定数ポインターを示します。aのみを指すように制限しbますが、 の値を変更することはできますb

それが役に立てば幸い!!!:)

于 2015-03-31T08:04:36.773 に答える