解除引用运算符与使用void *的数组偏移运算符给出不同的结果

时间:2012-04-05 18:02:16

标签: c++ arrays void-pointers dereference

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

// 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

使用方括号打印出我期望的结果。但解除引用指针偏移不会, ,即使数组是类型转换

为何出现差异?

3 个答案:

答案 0 :(得分:3)

那是因为你要取消引用该值然后添加&#39; i&#39;结果。你需要在指针转换周围使用更多的括号,或者使用更明显的static_cast。

如:

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

答案 1 :(得分:1)

printf("*(void_ary+%d) is %u\n", i, *((elem_type*)(void_ary))+i);

此处似乎您在向其添加i之前取消引用该值。这将导致始终获得数组的第一个元素(因为您将相同的指针解除引用5次)并向其添加i

尝试:

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

答案 2 :(得分:1)

你的表达并不意味着同样的事情。你写的是什么

*(void_ary+i)

实际上并非如此。实际上它是

void_ary[0]+i

根据您的printf符号。


如果你写

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

作为

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

然后我认为它变得更加清晰。您正在寻找:

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