0

私はポインターをよく理解しており、その使い方もよく理解しています。ただし、配列でのポインターの使用法を理解したことがありません。私はそれを行う方法を知っていますが、配列の直接操作よりもこれを使用する理由がわかりません。配列内のポインターを使用してのみ実行できることを知りたいだけです。ありがとう。

4

2 に答える 2

6

検討:

struct Match {
    int scores[30];
    char names[30][64];
    int ages[30];
    char description[1024];
};

この構造体の長さは 3184 バイトです。

Match matches[16];

マッチ[0]とマッチ[1]を交換する必要があると判断した場合、2つを交換するには、次の作業を行う必要があります(これが std::swap の実装方法です):

Match temp; // prepare 3184 bytes on the stack.
temp = matches[0]; // copy 3184 bytes
matches[0] = matches[1]; // copy 3184 bytes
matches[1] = temp; // copy 3184 bytes

それは、データのコピー/移動に多くのCPUサイクルです。

ポインターを使用した場合:

Match* matches[16];
for (size_t i = 0; i < 16; ++i) {
    mathces[i] = new Match;
}

std::swap がしなければならないのは、2 つのポインターを交換することだけです。

Match* temp = matches[0]; // 4 or 8 bytes
matches[0] = matches[1]; // 4 or 8 bytes
matches[1] = temp; // 4 or 8 bytes

はるかにクリーンで、最適化された場合、これはおそらくレジスターで実行でき、極端なパフォーマンスが得られます。

これのもう 1 つの利点は、メモリの節約です。4Mb または 8Mb (32/64 ビットに応じて) を占有する 1,000,000 個の Match ポインターの配列を持つことができ、その多くはnullptr. 現在有用なエントリへのポインタのみが必要です。

1,000,000 個の Match オブジェクトの配列には、3Gb の RAM が必要です。

逆に、1,000,000 個のポインターすべてが一意の Match オブジェクト インスタンスを指す必要がある場合、最大 3Gb のオブジェクトと最大 1Mb のポインターが必要になります。

于 2013-11-03T19:56:08.493 に答える
0

ご覧のとおり、配列はオブジェクトとは異なります。配列自体がメモリをブロックとして割り当てています。次に、配列には値へのポインターが含まれます。これは、array1 = array2 を実行できることを意味します。値自体はコピーされず、アドレスのみがコピーされます。

配列がポインターである理由は、メモリ管理のためです。配列を複製するのは簡単すぎます。配列はオブジェクトのようには機能しません。

配列のインデックス 1 にアクセスすると、配列に次のように尋ねられます。この配列のインデックス 1 に格納されているアドレスの値を教えてください。

私はC++、特にポインターが得意ではありませんが、これがどのように機能するかはかなり確信しています。

于 2013-11-03T19:58:22.960 に答える