int [9]和[3] [3]

时间:2016-09-16 17:34:34

标签: c arrays multidimensional-array

之间有什么区别
#include <stdio.h>

int a[9]; 

int
main()
{
    printf("%d\n", a[1]);
}

#include <stdio.h>

int a[3][3]; 

int
main()
{
  printf("%d\n", a[1]);
}

我认为两者都导致在.bss部分放置相同的36字节内存缓冲区,有什么区别?或者是a[3][3]语法糖超过a[9] - a[3*3]

3 个答案:

答案 0 :(得分:6)

不,他们相同,他们代表不同的类型。参考你的代码,

  • 在第一种情况下,a是一维数组。因此,a[1]属于int类型。

    §)要打印该值,%d没问题。

  • 然而,在第二种情况下,a是一个二维数组。因此,a[1]的类型为int [3]

    §)当作为函数参数传递时,它会衰减到指向第一个元素的指针,基本上是int *。根据{{​​1}}格式说明符的要求,您需要%p打印它(并将指针强制转换为void *。)

    < / LI>

但是,如果您对这两个变量的内存布局感到困扰,可以查看other answer by AnTanother one有关多维数组内存布局的详细信息。

答案 1 :(得分:3)

int a[3][3]int a[9]上的语义糖。原始内存布局相同(即它是9 int s的连续块),但语言级访问语法不同。当a[3][3]作为a[i][j]访问时,编译器将明显的2D索引转换为使用i * 3 + j公式的1D索引。后一种索引转换方案可以很容易地扩展到任意数量的维度。

答案 2 :(得分:3)

  

之间有什么区别
int a1[9];
     

int a2[3][3];

(我已更改名称,因此我可以更轻松地讨论声明。)

不同之处在于它们的类型不同。它们都具有相同的底层内存布局,每个内存布局都是连续的内存区域,大小是int的9倍。但是a1是一个包含9个int个对象的数组,而a2是一个包含3个对象的数组,每个对象都是3个int个对象的数组。它是一个多维数组,在C中恰好是一个数组数组,仅此而已。

区别不仅仅是语法糖。您可能会为某些操作获得相同的生成代码,例如a1[1]a2[0][1]。但是,例如,a1[3]引用数组a1的第4个元素,而a2[0][3],虽然您可能认为它指的是同一个东西,但实际上有未定义的行为。 (允许编译器执行运行时数组绑定检查,但不是必需的,并且允许假设数组引用不会超过索引数组对象的末尾。)

printf("%d\n", a2[1]);

正如其他人所说,这有不明确的行为。 a2[1]int[3]类型的数组对象。在大多数情况下,数组类型的表达式转换为指针类型的表达式,因此a2[1]最终为int*类型,并生成指向第二行{的初始元素的指针{1}}。要打印指针值,请使用a2 - 这需要类型为%p的参数,因此您需要强制转换它:

void*

推荐阅读:comp.lang.c FAQ的第6部分。