2010-02-04 4 views
0

Pour une matrice 4-D, j'essaie de faire la moyenne des valeurs en utilisant une notation de pointeur compact. En utilisant des exemples de mon texte, il est dit que je peux utiliser quelque chose comme ceci:Fin de la matrice multidimensionnelle à l'aide de la notation de pointeur compact

void DisplayAverage(double (*set)[DIM1][DIM2][DIM3]) 
    double *ptr; 
double subTotal2 = 0; 
    for (ptr = (double *)set; ptr < (double *)set + DIM0 * DIM1 * DIM2 * DIM3; ptr++) { 
    subTotal2 += *ptr; 
    subTotal2 /= (DIM0 * DIM1 * DIM2 * DIM3); 
cout << "Using compact pointer operations, total: " << subTotal2 << "\n"; 
    } 
} 

Ce code fonctionne. Cependant, si j'essaie d'utiliser une autre notation du texte:

for (ptr = (double *)set; ptr < (double *)(&set + 1); ptr++) { 

pour accéder au tableau, je n'obtiens aucune sortie. Des pensées? Merci.

+0

Re-étiquetée avec le langage de programmation "C++" attaché - il ressemble certainement C++ , s'il vous plaît corriger si non. –

Répondre

2

Vous avez une adresse de trop:

// notice: "set" instead of "&set" 
for (ptr = (double *)set; ptr < (double *)(set + DIM0); ptr++) { 

Vous ajoutiez un à l'adresse de votre paramètre (et donc pointaient à Nowhereland), au lieu de DIM0 à la valeur de votre paramètre (qui vous amènera à après les données de tableau, qui est votre objectif). Notez que le paramètre est un pointeur vers un tableau de dimensions [DIM1][DIM2][DIM3]. En d'autres termes, l'argument que vous passez à la fonction peut être un tableau de type double[DIM0][DIM1][DIM2][DIM3], qui se décompose en le type pointeur de ce paramètre. Vous avez DIM0 lignes, donc vous ajoutez DIM0 à ce pointeur pour atteindre la position après la dernière cellule.

Ce que vous aviez probablement à l'esprit était d'en ajouter un au pointeur de l'ensemble du tableau. Cela fonctionnera si vous avez la déclaration suivante, à la place.

void DisplayAverage(double (*set)[DIM0][DIM1][DIM2][DIM3]); 

Vous devez maintenant passer l'argument en utilisant &arg au lieu de simplement arg, passer en fait l'adresse du tableau, au lieu de laisser la pourriture à son type de dimension intérieure. La boucle peut alors être écrite comme

for (ptr = (double *)set; ptr < (double *)(set + 1); ptr++) { 
1

Votre expression (&set + 1) indiquerait un passé tableau si défini était un tableau, mais il est pas. La variable est un pointeur dans le déguisement (pas un tableau), comme le sont tous les tableaux qui semblent avoir été transmis par valeur.

meilleur exemple:

void g(int a[3]); 
// exactly the same as: 
void g(int* a); 
// note the 3 is ignored by the compiler here! it serves as documentation when 
// reading the code, but nothing else, and for this reason you should pretty much 
// always drop it, preferring: 
void g(int a[]); /*or*/ void g(int* a); // (which are also identical) 

void f() { 
    int a[3] = {0, 1, 2}; 
    int* end = (int*)(&a + 1); // &a has type int (*)[3] (that's pointer to array 
    // of 3 ints so &a + 1 has the same value as &a[2] + 1 ("one past" the last 
    // valid item in a) 

    int* p = a; // this is how a is passed "by value" to a function such as g 
    end = (int*)(&p + 1); // even though this "looks" the same, &p has type int** 
    // and adding 1 to that has no correlation with what p points to. 
    // to make matters worse, the cast (and C++-style casts have the same problem 
    // here) hides this type error and makes the compiler believe we know what 
    // we're doing 

    // pointers are not arrays, even though they mostly behave similarly: 
    std::cout << sizeof(a) << ", " << sizeof(p) << ", " << sizeof(void*) << '\n'; 
    // compare the int* size to void* size 
} 

Et par exemple appliquer à des pointeurs à des tableaux:

typedef int T[3]; 
void g(T a[3]); 
// same as: 
void g(T a[]); /*and*/ void g(T* a); 

// that T happens to be an array type doesn't change anything, these are 
// also declaring the same function: 
void g(int a[][3]); /*and*/ void g(int (*a)[3]); 

void f() { 
    int a[3][3] = {}; 
    int* end = (int*)(&a + 1); 
    // note that end - &a[0][0] is 9 

    int* p = &a[0][0]; 

    std::cout << sizeof(a) << ", " << sizeof(p) << ", " << sizeof(void*) << '\n'; 
} 
Questions connexes