传递常量矩阵
参考这个 问题,尤其是已接受的 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
的指针转换为指向 int
的指针代码>const int。因此,以下内容有效:
func(const int a[]) // aquivalent: func(const int *a)
{ ... }
int main()
{
int b[10];
func(b);
return 0;
}
但 C/C++ 不会将指向 n 个 int 数组的指针隐式转换为指向 n 个 const int 数组的指针。即使包含 n 个 int 的数组会隐式转换为包含 n 个 const int 的数组。不支持隐式转换中的这种间接级别。以下内容将被拒绝(至少在 C 中会出现警告):
func(const int a[][n]) // aquivalent: func(const int (*a)[n])
{ ... }
int main()
{
int b[m][n];
func(b);
return 0;
}
这类似于 C++ 不会将类型 A 的模板隐式转换为类型 B 的模板,即使 A 可以隐式转换为 B 的问题。两个模板的类型完全不同。
这是正确的答案吗?
Referring to this question and especially the accepted answer of litb, I wonder why the gcc complain about this:
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;
}
If I eliminate the const
the compiler keeps still. Did I something misunderstand? I wanted to be sure that func
don't modify my array.
EDIT: The same thing happens if I define a data type for my matrix:
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;
}
I accept, this kind of code isn't very C style, more like C++. In C++ indeed there would be no problem if I define Array as a class containing all the matrix behavior.
class Array {...};
I suppose, I didn't understand very well the concept of arrays and arrays of arrays in C and passing them to functions. Any enlightenment?
Thank you in advance.
EDIT2: Meanwhile I chewed a bit on this problem and it seems to converge to the following question: C/C++ implicitly converts a pointer to an int
to a pointer to an const int
. Thus the following works:
func(const int a[]) // aquivalent: func(const int *a)
{ ... }
int main()
{
int b[10];
func(b);
return 0;
}
But C/C++ don't implicitly converts a pointer to an array of n int
s to a pointer to an array of n const int
s. Even though an array of n int
s is implicitly converted to an array of n const int
s. This level of indirection in the implicit conversion isn't supported. The following will be rejected (at least with a warning in C):
func(const int a[][n]) // aquivalent: func(const int (*a)[n])
{ ... }
int main()
{
int b[m][n];
func(b);
return 0;
}
It's similar to the problem that C++ doesn't implicitly convert a template for the type A into a template of type B even if A can be implicitly converted to B. The two templates are of completely different types.
Is this the right answer?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的
i
变量是一个包含 3 个元素的数组。当您将它传递给函数时,在函数内部,它变成指向第一个元素的指针。编译器可以将
const
添加到指针或指向的内容:3 个 int 的数组。然而,它不能将指向的内容从3 个整数的数组更改为3 个常量的数组。我认为你需要自己做演员。
Your
i
variable is an array with 3 elements.When you pass it to a function, inside the function, it becomes a pointer to the first element. The compiler can add
const
either to the pointer or to the thing pointed to: an array of 3 ints. It cannot however change the thing pointed to from an array of 3 ints to an array of 3 constants.I think you need to do the cast yourself.
您不需要消除 const,只需通过将调用中的参数强制转换为 func 来传递兼容的值:
如果可能,最好将 i 声明为 const,但此 hack 应该有效。
You don't need to eliminate const, just pass a compatible value by casting the argument in the call to func:
If possible, it would be preferrable to declare i as const, but this hack should work.