C++ 数组-为什么下标运算符与标识符绑定?

C++ 数组-为什么下标运算符与标识符绑定?,c++,c,arrays,operators,C++,C,Arrays,Operators,为什么数组的下标运算符与标识符绑定 因为当我们写作时: int a[5]; a实际上是“int[5]类型” 这禁止使用以下各项: typedef int[3][3] matrix_t; .... void foo(matrix_t my_matrix){ .... } 实际实施的好处是什么? 我真的很想拥有这个功能,还是错过了什么?这只是早期C语言开发的历史遗产。当时,人们决定实体的声明应该模仿其未来的用法。因此,数组声明看起来类似于表达式中使用数组的方式。这同样适用于函数声明、指针声明

为什么数组的下标运算符与标识符绑定

因为当我们写作时:

int a[5];
a实际上是“int[5]类型”

这禁止使用以下各项:

typedef int[3][3] matrix_t;
....
void foo(matrix_t my_matrix){
  ....
}
实际实施的好处是什么?


我真的很想拥有这个功能,还是错过了什么?

这只是早期C语言开发的历史遗产。当时,人们决定实体的声明应该模仿其未来的用法。因此,数组声明看起来类似于表达式中使用数组的方式。这同样适用于函数声明、指针声明等(指针声明中的
*
也“绑定到标识符”)

在现代C++中,在某些上下文中,你可以实际使用新语法,它遵循你所建议的逻辑。它适用于对typename别名使用声明(类似于经典的typedef声明)

或类似于函数返回类型声明的上下文

auto foo() -> int (*)[3]
{
  ...

// Same as
// int (*foo())[3]

它只是C语言发展早期的一个历史遗产。当时,人们决定实体的声明应该模仿其未来的用法。因此,数组声明看起来类似于表达式中使用数组的方式。这同样适用于函数声明、指针声明等(指针声明中的
*
也“绑定到标识符”)

在现代C++中,在某些上下文中,你可以实际使用新语法,它遵循你所建议的逻辑。它适用于对typename别名使用声明(类似于经典的typedef声明)

或类似于函数返回类型声明的上下文

auto foo() -> int (*)[3]
{
  ...

// Same as
// int (*foo())[3]

在C语言中,您可以按照使用变量的方式键入变量

它们有点像“冻结的表达”

所以

这意味着您将使用
x
,首先在
[]
中传递一个小于等于
5
的值,然后在
[]
中传递一个小于等于
2
的值,然后将该值分配给一个
int

从某种意义上说,这将重用表达式解析引擎来键入内容

typedef
的工作原理类似于声明一个变量,除非该变量将成为该类型的别名。所以不是

typedef int[3][3] matrix_t;
是的

同样,这将重用变量声明解析/语法来定义类型别名

在C++11中,我们使用的
更符合您的需要:

using matrix_t = int[3][3];

问题的最后一部分是C中的矩阵不能复制或按值传递
int[3][3]
类型,函数参数变为
int[3]*
types——指向
int[3]
s的指针。并且不能返回
int[3][3]
type句点

在C++中,这是通过<代码> STD::数组< /CO> >:< /P>固定的。
std::array< std::array< int, 3 >, 3 >

它在内存中的布局与上面的std::array相同,并且可以像值一样传递给函数或从函数传递给函数。

在C中,可以按照使用变量的方式键入变量

它们有点像“冻结的表达”

所以

这意味着您将使用
x
,首先在
[]
中传递一个小于等于
5
的值,然后在
[]
中传递一个小于等于
2
的值,然后将该值分配给一个
int

从某种意义上说,这将重用表达式解析引擎来键入内容

typedef
的工作原理类似于声明一个变量,除非该变量将成为该类型的别名。所以不是

typedef int[3][3] matrix_t;
是的

同样,这将重用变量声明解析/语法来定义类型别名

在C++11中,我们使用的
更符合您的需要:

using matrix_t = int[3][3];

问题的最后一部分是C中的矩阵不能复制或按值传递
int[3][3]
类型,函数参数变为
int[3]*
types——指向
int[3]
s的指针。并且不能返回
int[3][3]
type句点

在C++中,这是通过<代码> STD::数组< /CO> >:< /P>固定的。
std::array< std::array< int, 3 >, 3 >

它的内存与上面的代码> STD::Sturtual具有相同的布局,可以传递到/Value.t/P>>代码> TyWIFF int MatRXXT(3)[3 ] < /> >或<代码>,使用MatRIXTH= INT[INT] 3 [3 ] < /Cord>这是C++,只是右选一个…C和C++是不同的语言。请删除不相关的标签<代码> TyPulfIn Matrxt(3)[ 3 ] <代码>或<代码>使用MatRXXT=int [ 3 ] [3 ] < /Cord>这是C++唯一正确的选择一个…C和C++是不同的语言。请删除不相关的标签!每种语言都有它的语法。不知道你说的“遗产”是什么意思;这就是C的设置方式。这句话也适用于其他任何语言。@Olaf:我只是在评论为什么语法在最初设置时是这样设置的。你们知道,我们并没有从外太空收到石碑上的C语法。语法是由人创造的。这就是为什么他们以这种特定的方式创建了它(或者至少是一些来源在“为什么”这个问题上所陈述的),我的观点是“遗留”的论点对于每一种编程语言都是正确的,包括相对较新的Go、Rust或Swift。有一些语法选择,后来的版本必须使用它(至少在语言有足够大的用户基础时)。每种语言都有它的语法。不知道你说的“遗产”是什么意思;这就是C的设置方式。这句话也适用于其他任何语言。@Olaf:我只是在评论为什么语法在最初设置时是这样设置的。你们知道,我们并没有从外太空收到石碑上的C语法。语法是由人创造的。这就是为什么他们以这种特定的方式创建了它(或者至少是一些来源在“为什么”这个问题上所陈述的),我的观点是“遗留”的论点对于每一种编程语言都是正确的,包括相对较新的Go、Rust或Swift。有一些语法选择和更高版本必须使用它(一旦