多维数组中的括号顺序

时间:2020-01-29 18:54:00

标签: c language-design

int数据[3] [5];

是5元素数组的3元素数组。

为什么?从直觉上来说,如果int[3]是3元素数组,而int[3][5]应该是3元素数组的5元素数组。

3 个答案:

答案 0 :(得分:5)

直觉应该来自于索引约定-因为它是一个数组数组,所以第一个索引选择元素这是一个数组,第二个索引选择的是选定数组的元素。那是:

data[2][4]将选择数组编号2中的元素编号4(注意零基础)。

现在,正如您指出的那样,这样的数组的定义似乎有点违反直觉,但显然,这种方式只是为了与索引语法保持一致,否则会更加混乱。

答案 1 :(得分:1)

由于spiral rule之类的问题,C并非总是以直观的方式工作,尽管也许您在这里误用了它。

与任何一种语言一样,您需要接受其本身的语法,而不是您认为的语法,否则您将在语义层次上不断与该语言作斗争。

诸如cdecl之类的工具将其解释为:

将数据声明为int数组5的数组3

答案 2 :(得分:1)

这不符合C的声明符的概念。在声明程序中指定声明的指针性,数组性或功能性,而 type -ness由类型说明符 1 指定:< / p>

int *p;              // *p is the declarator
double arr[N][M];    // arr[N][M] is the declarator
char *foo( int x );  // *foo( int x ) is the declarator

这允许您以紧凑的方式创建任意复杂的类型:

int *(*foo(void))[M][N];

foo是一个不带参数的函数,它返回指向int的N元素数组的M元素数组的指针。

因此,对象或函数的实际类型是通过类型说明符(和任何限定符)和声明符的 combination 来指定的。

不幸的是,“紧凑”只是说“让人眼花another乱”的另一种方式。这样的声明可能很难阅读和理解。这确实意味着诸如多维数组声明之类的内容读为“向后”:

  +---------------------------------+
  |                                 |
  v                                 |
type   arr -> array-of -> array-of -+
        ^
        |
    start here

但是,如果您逐步进行,这确实是有道理的。让我们从一些任意类型T开始。我们将T的数组声明为

T arr[N];

因此,arrT 的N个元素数组。现在我们将T替换为数组类型R [M]。这给了我们

R arr[N][M];

arr仍然是某物的N元素数组,而某物是R [M],这就是为什么我们写arr[N][M]而不是{{1 }}。


  1. 也有存储类限定符,类型限定符等,但是我们不在这里讨论。