传递一个常数矩阵

时间:2009-08-27 10:29:30

标签: c arrays pointers parameters const

参考this问题,尤其是被接受的answer litb,我想知道为什么gcc抱怨这个:

void func(const int (*ip)[3]) {
    printf("Value: %d\n", ip[1][1]);
}

int main() {
    int i[3][3] = { {0, 1, 2} , {3, 4, 5}, {6, 7, 8} };
    func(i);
    return 0;
}

如果我消除const编译器保持静止。我有什么误解吗?我想确保func不修改我的数组。

编辑:如果我为矩阵定义数据类型,也会发生同样的事情:

typedef int Array[3][3];

void func(const Array *p) {
    printf("Value: %d\n", (*p)[1][1]);
}

int main() {
    Array a = { {0, 1, 2}, {3, 4, 5}, {6, 7, 8} };
    func(&a);
    return 0;
}

我接受,这种代码不是很C风格,更像是C ++。在C ++中,如果我将Array定义为包含所有矩阵行为的类,确实没有问题。

class Array {...};

我想,我不太了解C中数组和数组数组的概念,并将它们传递给函数。任何启示?

提前谢谢。

EDIT2:与此同时,我对此问题略微嗤之以鼻,似乎收敛到以下问题:C / C ++隐式将指向int的指针转换为指向{的指针{1}}。因此,以下工作:

const int

但是C / C ++不会将指向n func(const int a[]) // aquivalent: func(const int *a) { ... } int main() { int b[10]; func(b); return 0; } s数组的指针隐式转换为指向n int s数组的指针。即使n const int s的数组被隐式转换为n int s的数组。不支持隐式转换中的这种间接级别。以下内容将被拒绝(至少在C中有警告):

const int

类似于C ++不会隐式地将类型A的模板转换为类型B的模板的问题,即使A可以隐式转换为B.这两个模板的类型完全不同。

这是正确的答案吗?

2 个答案:

答案 0 :(得分:2)

您的i变量是一个包含3个元素的数组。

当你将它传递给函数时,在函数内部,它成为指向第一个元素的指针。编译器可以将const添加到指针或指向的事物: 3个int的数组。然而,它不能改变从 3个整数的数组指向 3个常量的数组的东西。

我认为你需要自己做演员。

#include <stdio.h>

typedef const int array_of_3_constants[3];

void func(int (* const i)[3]) {
  ++i[0][0];
  printf("Value: %d\n", i[1][1]);
}

void gunc(array_of_3_constants *i) {
  ++i[0][0];                              /* error */
  printf("Value: %d\n", i[1][1]);
}

int main(void) {
  int i[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}};
  func(i);
  func((array_of_3_constants*)i);         /* warning */
  gunc(i);                                /* warning */
  gunc((array_of_3_constants*)i);
  return 0;
}

答案 1 :(得分:1)

您不需要消除const,只需通过在func调用中转换参数来传递兼容值:

   func( (void *)i );

如果可能的话,最好将i声明为const,但这个hack应该可行。