30

I've often used pointers to const objects, like so...

const int *p;

That simply means that you can't change the integer that p is pointing at through p. But I've also seen reference to const pointers, declared like this...

int* const p;

As I understand it, that means that the pointer variable itself is constant -- you can change the integer it points at all day long, but you can't make it point at something else.

What possible use would that have?

4

11 に答える 11

30

組み込みシステム用の C プログラム、または同じメモリ (メモリを共有するマルチプロセッサ アプリケーション) を参照する必要がある特別な目的のプログラムを設計している場合は、定数ポインタが必要です。

たとえば、小さな LCDが取り付けられた32 ビット MIP プロセッサがあります。LCD データをメモリ内の特定のポートに書き込む必要があり、それが LCD コントローラに送信されます。

その数値を #define することもできますが、それをポインターとしてキャストする必要があり、その場合、C コンパイラーにはそれほど多くのオプションがありません。

さらに、キャストすることもできる揮発性にする必要があるかもしれませんが、提供されている構文 (揮発性メモリの場所への const ポインター) を使用する方が簡単で明確です。

PC プログラムの場合の例: DOS VGA ゲームを設計する場合 (基本的な低レベル グラフィックスを学習するための楽しいオンライン チュートリアルがあります)、VGA メモリに書き込む必要があり、オフセットとして参照される場合があります。 const ポインターから。

-アダム

于 2008-10-20T21:16:05.440 に答える
29

これにより、ポインターが変更されないように保護できます。これは、ポインターが変更されないことに基づいて作成した仮定を保護したり、意図しない変更から保護したりできることを意味します。次に例を示します。

int* const p = &i;

...

p++;     /* Compiler error, oops you meant */
(*p)++;  /* Increment the number */
于 2008-10-20T21:19:32.937 に答える
8

別の例: 初期化された場所がわかっている場合は、将来の NULL チェックを回避できます。コンパイラは、ポインターが (NULL に) 決して変更されないことを保証します…</p>

于 2008-10-20T21:16:07.047 に答える
6

const 以外の C++ メンバ関数では、ポインタthisの型はです。. メンバー関数の場合、タイプはです。(めったに遭遇しませんが)およびメンバー関数もあり、これにも修飾子があります。C * constCCconstthisconst C * constvolatileconst volatilethisvolatile

于 2008-10-20T21:16:57.760 に答える
5

1 つの用途は、ハードウェア ピンなどの入力/出力デバイスにマップされた特定のアドレスを参照する必要がある低レベル (デバイス ドライバーまたは組み込み) コードです。一部の言語では、特定のアドレスで変数をリンクできます (例: Ada has use at)。C でこれを行う最も慣用的な方法は、定数ポインターを宣言することです。volatileこのような使用法には修飾子も必要であることに注意してください。

それ以外の場合は、防御的なコーディングです。変更してはならないポインターがある場合は、変更できないように宣言するのが賢明です。これにより、コンパイラ (および lint ツール) が誤った変更の試みを検出できるようになります。

于 2008-10-20T21:43:35.367 に答える
4

ポインターへの意図しない変更 (ポインター演算や関数内など) を避けたい場合は、常にそれらを使用してきました。シングルトン パターンにも使用できます。

'this' は、ハードコードされた定数ポインターです。

于 2008-10-20T21:17:21.520 に答える
3

「const int」と同じ...コンパイラーが変更されないことを知っている場合、それに基づく最適化の仮定である可能性があります。

struct MyClass
{
    char* const ptr;
    MyClass(char* str) :ptr(str) {}

    void SomeFunc(MyOtherClass moc)
    {
         for(int i=0; i < 100; ++i)
         { 
                 printf("%c", ptr[i]);
                 moc.SomeOtherFunc(this);
         }
    }
}

ここで、コンパイラはそのループを最適化するためにかなりのことを行うことができます --- SomeOtherFunc() が ptr の値を変更しないことがわかっている場合。const を使用すると、コンパイラはそれを認識し、仮定を立てることができます。これがないと、コンパイラは SomeOtherFunc が ptr を変更すると想定する必要があります。

于 2008-10-20T21:10:25.293 に答える
2

コードの外部から渡されたオブジェクトがあり、それを操作するには、渡された特定のメモリにアクセスする必要がある OLE コードを見たことがあります。 OLE インターフェイスを介して入ってきたものよりも。

于 2008-10-20T21:16:47.807 に答える
1

この質問に対する回答として、いくつかの正当な理由が示されています (メモリ マップ デバイスと単純な古い防御コーディング)。 to item は const へのポインターです。

確かに、この予感を裏付けるデータはありませんが、それでも賭けはします。

于 2008-10-20T21:38:16.050 に答える
0

type*const type*は型そのものと考えてください。次に、これらの型の const が必要な理由がわかります。

于 2008-10-20T22:19:39.973 に答える
-2

ポインターは常に int と考えてください。この意味は

object* var;

実際には次のように考えることができます

int var;

つまり、const ポインターは単に次のことを意味します。

const object* var;

になる

const int var;

したがって、ポインターが指すアドレスも変更できません。それだけです。データの変更を防ぐには、const オブジェクトへのポインターにする必要があります。

于 2008-10-20T21:30:49.637 に答える