关于c ++:取消引用运算符与使用void *的数组偏移运算符给出不同的结果

Dereference operator gives different results than array offset operator with void*

下面的C++ Win32控制台程序将一个数组分配给一个空指针,并以两种不同的方式打印结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 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
"
, i, *((elem_type*)(void_ary))+i);
    }

    void *allocd_ary;
    return 0;
}

以下是输出:

1
2
3
4
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

使用方括号打印我期望的结果。但是,取消引用指针偏移量不会,即使数组正在进行类型转换。

为什么存在差异?


这是因为你正在取消对值的引用,然后在结果中添加"i"。您需要在指针转换周围使用更多的括号,或者使用更明显的静态转换。

如:

*(static_cast(void_ary)+i)


你的表情不一样。你写的东西

1
*(void_ary+i)

不是真的吗?实际上是

1
void_ary[0]+i

根据你的printf符号。

如果你写信

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

作为

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

然后我想事情变得更清楚了。您正在寻找:

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


1
2
printf("*(void_ary+%d) is %u
"
, i, *((elem_type*)(void_ary))+i);

在这里,在添加i之前,您似乎正在取消引用值。这将导致始终获取数组的第一个元素(因为您5次取消对同一指针的引用),并向它添加i

尝试使用:

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