首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >int a[9]与a[3]的差异[3]

int a[9]与a[3]的差异[3]
EN

Stack Overflow用户
提问于 2016-09-16 17:34:33
回答 3查看 245关注 0票数 0

两者有什么区别?

代码语言:javascript
复制
#include <stdio.h>

int a[9]; 

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

代码语言:javascript
复制
#include <stdio.h>

int a[3][3]; 

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

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-09-16 17:54:40

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

票数 3
EN

Stack Overflow用户

发布于 2016-09-16 17:36:28

不,它们是而不是,它们代表不同的类型。关于你的代码,

  • 在第一种情况下,a是一个一维数组。因此,a[1]int类型的。 §)打印值时,%d很好。
  • 然而,在第二种情况下,a是一个二维数组.因此,a[1]int [3]类型的。 §)当作为函数参数传递时,它会衰减到指向第一个元素的指针,基本上是一个int *。您将需要%p来打印它(并按照void *格式说明符的要求,将指针转换为void *__ )。

但是,如果您对这两个变量的内存布局感到烦恼,您可以检查AnT的其他答复另一个,后者详细介绍了多维数组的内存布局。

票数 6
EN

Stack Overflow用户

发布于 2016-09-16 18:21:09

两者有什么区别? int a19; 和 int a23;

(我已经更改了名称,以便更容易地讨论声明。)

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

不同之处不只是句法上的糖。对于某些操作,您可能会得到相同的生成代码,例如a1[1]a2[0][1]。但是,例如,a1[3]引用数组a1的第4个元素,而a2[0][3] (尽管您可能认为它引用的是相同的东西)实际上具有未定义的行为。(编译器允许但不需要执行运行时数组绑定检查,并且允许假定数组引用不会超过索引数组对象的末尾。)

代码语言:javascript
复制
printf("%d\n", a2[1]);

正如其他人所提到的,这是一种未定义的行为。a2[1]int[3]类型的数组对象。在大多数上下文中,数组类型的表达式被转换为指针类型的表达式,因此a2[1]int*类型结束,并生成指向a2第二行的初始元素的指针。要打印指针值,请使用%p --这需要一个void*类型的参数,因此您需要转换它:

代码语言:javascript
复制
printf("%p\n", a2[1]);

推荐阅读:常见问题解答第6节。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39537204

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档