以下是二维数组的示例。
int s[5][2] = {
{0, 1},
{2, 3},
{4, 5},
{6, 7},
{8, 9}
};
int (*p)[2];
如果我写p = &s[0];
则没有错误。但是,如果我写p = s[0];
,则会出现错误,即使&s[0]
和s[0]
会给出相同的地址。
请告诉我为什么会有不同之处,即使两者都有相同的地址。
答案 0 :(得分:15)
地址相同,但类型不同。
&s[0]
的类型为int (*)[2]
,但s[0]
的类型为int [2]
,已衰减为int *
。
结果是,当对p
执行算术时,它遍历数组的模式将取决于其类型。如果您撰写p = &s[0]
然后访问p[3][1]
,则表示您正在访问s[3][1]
。另一方面,如果您编写int *q = s[0]
,则只能使用q
来访问s
的第一个子数组,例如q[1]
将访问s[0][1]
。
答案 1 :(得分:0)
关闭,但不完全。 s是指向数组第一个元素的指针。它也是该数组的别名 - 编译器知道它指向特定数量的元素。
因此,& s [0]返回第一个元素的地址,而s [0]返回元素本身。
然而,* p只是指向int的指针。它可能是更多的元素,但编译器肯定不知道。
答案 2 :(得分:-2)
(int *)
分配给不同的数据类型(int **)
时,gcc 会显示警告。不确定其他编译器。