2012-04-05 4 views
0

Das folgende C++ Win32-Konsole-Programm ein Array zu einem Zeiger zuweist ungültig zu erklären, und druckt die Ergebnisse auf zwei verschiedene Arten:Dereferenzierungsoperator gibt unterschiedliche Ergebnisse als Array Offset-Operator mit 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; 
} 

Hier ist die Ausgabe :

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 

Die Verwendung von eckigen Klammern gibt das Ergebnis aus, das ich erwartet habe. Das Dereferenzieren von Zeigerversätzen führt jedoch nicht zu , obwohl das Array typecast wird.

Warum die Diskrepanz?

Antwort

3

Nun, das liegt daran, dass Sie den Wert dereferenzieren und dann 'i' zum Ergebnis hinzufügen. Sie benötigen einige weitere Klammern um die Pointer-Cast oder verwenden Sie static_cast, die offensichtlicher ist.

Wie in:

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

+0

Okay, mein Schlechter. Das zweite printf nimmt nur den Wert des ersten Elements und fügt 1 hinzu. Sollte printf sein ("* (void_ary +% d) ist% u \ n", i, * (((elem_type *) (void_ary)) + i)); – Buggieboy

+1

Korrekt, deshalb sind es nicht die vier verschiedenen Elemente, sondern das gleiche, das viermal mit i addiert und ausgedruckt wird, wobei ich bei 0 anfange. Manchmal ist es rutschig, mach dir keine Sorgen. –

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

scheint es hier, dass Sie den Wert sind dereferencing VOR i ihm hinzufügen. Dies führt dazu, dass immer das erste Element des Arrays abgerufen wird (da Sie den gleichen Zeiger fünfmal dereferenzieren) und fügen Sie i hinzu.

Versuchen mit:

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

Ihr Ausdruck nicht das gleiche bedeuten. Was schreiben Sie als

*(void_ary+i) 

Ist eigentlich nicht das. Tatsächlich ist es

void_ary[0]+i 

entsprechend Ihrer printf Notation.


Wenn Sie schreiben

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

als

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

dann denke ich, es wird klar. Sie suchen:

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