为什么数组的下标运算符与标识符绑定?
当我们写的时候Cuz:
int a[5];
a实际上是“int [5]”类型
禁止使用以下内容:
typedef int[3][3] matrix_t;
....
void foo(matrix_t my_matrix){
....
}
实际实施的好处是什么?
我真的想拥有这个功能,还是我想念一些东西?
答案 0 :(得分:2)
在C中,您可以按照您使用它们的方式输入变量。
他们有点像#34;冷冻表达"。
所以
int x[5][2];
表示您使用x
首先将5
中的值传递给[]
,然后2
中的值最多为[]
你赋予该值的是int
。
从某种意义上说,这会重复使用表达式解析引擎来输入内容。
typedef
的作用类似于声明一个变量,除了该变量将成为该类型的别名之外。而不是
typedef int[3][3] matrix_t;
它是
typedef int matrix_t[3][3];
再次,这将重用变量声明解析/语法来定义类型别名。
在C ++ 11中,我们using
更像你想要的工作:
using matrix_t = int[3][3];
问题的最后一部分是C中的矩阵无法按值复制或传递。 int[3][3]
类型作为函数参数变为int[3]*
类型 - 指向int[3]
的指针。并且您无法返回int[3][3]
类型的期间。
在C ++中,这是通过std::array
:
std::array< std::array< int, 3 >, 3 >
是一种与int[3][3]
兼容的布局类型(至少在实践中),但可以像函数一样传递给函数。在C中你做:
struct matrix {
int data[3][3];
};
在内存中的布局与上面的std::array
相同,可以像函数一样传递给函数。
答案 1 :(得分:1)
这只是C语言发展早期的历史遗产。当时决定实体的声明应该模仿其未来的使用。因此,数组声明看起来类似于表达式中数组的使用方式。这同样适用于函数声明,指针声明等。(指针声明中的*
也是&#34;绑定到标识符&#34;)
在现代C ++中,在某些情况下,您实际上可以使用新语法,该语法遵循您建议的逻辑。它适用于typename别名的using声明(类似于经典的typedef-declaration)
using array_type = int[3];
// Same as
// typedef int array_type[3];
或类似函数返回类型声明的上下文
auto foo() -> int (*)[3]
{
...
// Same as
// int (*foo())[3]