使用紧凑指针表示法结束多维数组

时间:2010-02-04 01:53:20

标签: c++ pointers

对于4-D数组,我试图使用紧凑指针表示法对值进行平均。使用我的文本中的示例,它说我可以使用这样的东西:

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++) {

访问数组,我没有输出。有什么想法吗?感谢。

3 个答案:

答案 0 :(得分: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 :(得分:1)

如果 set 是一个数组,那么你的表达式(&set + 1)会指向一个数组,但它不是。变量 set 是伪装的指针(不是数组),所有数组看起来都像是按值传递。

更好的例子:

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

答案 2 :(得分:0)

我建议不要在C ++中使用静态多维数组。请参阅How to initialize 3D array in C++

中的回复