2010-02-04 40 views
0

對於4維數組,我試圖使用緊湊指針表示法對這些值求平均值。使用我的文本中的示例,它說我可以使用像這樣的東西:使用緊湊指針表示法的多維數組結束

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"; 
    } 
} 

該代碼有效。但是,如果我嘗試從文本中使用另一種表示法:

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

要訪問數組,我得不到輸出。有什麼想法嗎?謝謝。

+0

重新加標籤的編程語言「C++」連接 - 它肯定看起來像C++如果不是,請更正。 – 2010-02-04 01:57:19

回答

2

你有地址之一太多:

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

你是你的參數值加一來你的參數的地址(並因此被指向nowhereland),而不是DIM0(其會在數組數據之後給你,這是你的目標)。

請注意,參數是一個指向尺寸爲[DIM1][DIM2][DIM3]的數組的指針。換句話說,傳遞給函數的參數可以是類型爲double[DIM0][DIM1][DIM2][DIM3]的數組,該數組將衰減爲該參數的指針類型。你有DIM0行,所以你添加DIM0到那個指針到達最後一個單元之後的位置。

你可能想到的是將一個指針加到整個數組的指針上。如果您有以下聲明,這將起作用。

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

現在,您需要使用&arg,而不是僅僅arg,實際上傳遞數組的地址,而不是讓它腐爛其內部尺寸類型傳遞參數。然後循環可以寫爲

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

你表達(&set + 1)響應將指向一個過去的數組,如果設置是一個數組,但它不是。變量集合是一個變相指針(不是一個數組),所有數組看起來像是按值傳遞的。這

更好的例子:

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 
} 

而且例如它應用到指針到數組:

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'; 
}