0

次の C++ Win32 コンソール プログラムは、配列を void へのポインターに割り当て、結果を 2 つの異なる方法で出力します。

// Foo.cpp : A Win32 console application.
//
#include "stdafx.h"

typedef unsigned char elem_type;
#define ELEM_COUNT 4

int _tmain(int argc, _TCHAR* argv[])
{
    elem_type *ary = new elem_type[ELEM_COUNT];
    for (int i = 0; i < ELEM_COUNT; i++)
    {
        ary[i] = ((i + 1) * 5); // multiples of 5
    }
    void *void_ary = ary;

    for (int i = 0; i < ELEM_COUNT; i++)
    {
        printf("void_ary[%d] is %u\t", i, ((elem_type*)void_ary)[i]);
        printf("*(void_ary+%d) is %u\n", i, *((elem_type*)(void_ary))+i);
    }

    void *allocd_ary;
    return 0;
}

出力は次のとおりです。

void_ary[0] is 5        *(void_ary+0) is 5
void_ary[1] is 10       *(void_ary+1) is 6
void_ary[2] is 15       *(void_ary+2) is 7
void_ary[3] is 20       *(void_ary+3) is 8

角括弧を使用すると、期待どおりの結果が出力されます。ただし、配列が typecast されている場合でも、ポインター オフセットの逆参照は行われません。

なぜ不一致なのですか?

4

3 に答える 3

3

これは、値を逆参照してから結果に「i」を追加しているためです。ポインターキャストの周りにさらに括弧を付けるか、より明白な static_cast を使用する必要があります。

次のように:

*(static_cast<elem_type*>(void_ary)+i)

于 2012-04-05T18:04:08.140 に答える
1

あなたの表現は同じことを意味するものではありません。あなたが書くもの

*(void_ary+i)

実際にはそうではありません。実際には

void_ary[0]+i

あなたのprintf記法によると。


あなたが書くなら

*((elem_type*)(void_ary))+i

なので

*((elem_type*)(void_ary)) + i

そうすればもっとはっきりすると思います。あなたは探している:

*((elem_type*)(void_ary)+i)
于 2012-04-05T18:06:33.613 に答える
1
printf("*(void_ary+%d) is %u\n", i, *((elem_type*)(void_ary))+i);

ここでは、値を追加iする前に値を逆参照しているようです。これにより、常に配列の最初の要素が取得され (同じポインターを 5 回逆参照しているため)、それに追加iされます。

試してみてください:

*((elem_type*)(void_ary)+i)
于 2012-04-05T18:05:43.407 に答える