6


    //Example 1
    const double pie = 3.14;   //const object
    const double *cptr = &pie; //pointer-to-const to const object
    double *ptr = &pie;        //ERROR - non-pointer-to-const to const object

    //Example 2
    double pie = 3.14;         //non-const object
    const double *cptr = &pie; //non-pointer-to-const to non-const object
    double *ptr = &pie;        //non-pointer-to-const to non-const object


最初は、非constオブジェクトへのpointer-to-constは許可されていますが、これは、pointer-to-constが非constオブジェクトを変更しないことを意味するためです。

しかし、私はc ++の本で、非constオブジェクトへのpointer-to-constが許可されている理由を読みました。これは、pointer-to-constポインターが、それが指すオブジェクトがconstであるかどうかを実際に知る方法がないため、オブジェクトを処理するためです。 constとしてポイントしますが、同じロジックにより、non-pointer-to-constはconstオブジェクトをnon-constオブジェクトとして扱いますが、コンパイラーはコンパイル時にエラーをスローします。

ここで何かが足りませんか?

4

2 に答える 2

6

constを宣言すると、「この変数の値は変更されるべきではありません」と表示されます。

constへのポインタを宣言すると、「ポイントしている変数を変更するつもりはありません」と言います。


質問1:変数へのポインタにconstのアドレスが割り当てられていると、なぜエラーが発生するのですか?

// Example 1
const int i = 0;
int * p = &i;        /* Error */

回答:最初の行には「の値がi変更されないことを保証してください」と書かれているため、2行目では、コンパイラーはその保証を行うことができなくなります。ポインターの型情報はp、コンパイラーに通知するほど厳密ではありません。指示された値への変更を許可しますi


質問2: constへのポインターに変数のアドレスが割り当てられていると、エラーが発生しないのはなぜですか?

// Example 2
int j = 0;
const int * q = &j;  /* No error */

回答: constへのポインタは、「の値がを介してj変更されないことを保証してください」と言っているためです。const宣言へのポインターは、ポイントされた値が定数でなければならないことを意味するのではなく、ポインターを使用している人だけがポインターを使用して値を変更できないため、 viaが重要であることに注意してください。qq

于 2012-10-25T04:37:54.760 に答える
2

constへのポインタ

const double *p

指すオブジェクトを定数オブジェクトとして扱います。つまり、オブジェクトを変更することはできません。ポインタの参照を解除するとすぐに

*p

あなたは定数オブジェクトを扱っています。それを変更しようとすると、

*p = 1.0;

コンパイラからエラーメッセージが表示されます。

一方、非定数へのポインタ

double *p

指すオブジェクトを非定数として扱い、その値を変更できるようにします。

*p = 1.0;

合法になります。ただし、いつでも一定のオブジェクトがある場合

const double d = 1.0;

それを指す非定数へのポインタを作成することはできません。

double *p = &d;

コンパイラによって受け入れられません。そうです、コンパイラーは非定数へのポインターがそれが指すオブジェクトを変更できるようにします。ただし、定数オブジェクトを指す非定数へのポインタを作成することはできません。したがって、非定数へのポインタを使用して定数オブジェクトを変更できる状況に遭遇することはありません。

タイトルの質問について:これは主に言語設計の決定です。ただし、コンパイラが値を変更しないように特定のオブジェクトに依存できるという事実は、さまざまな最適化が可能であることを意味します。たとえば、同じポインタが2つの逆参照の間に他のコードがある関数で2回逆参照され、そのポインタが定数へのポインタである場合、コンパイラは実際にメモリから値を2回フェッチする必要はないと想定します。これは、最初の逆参照と2番目の逆参照の間で値を変更することは許可されていないためです。

于 2012-10-25T04:17:08.083 に答える