正如我的老师告诉我的那样,数组声明不能接受地址作为赋值。
int a[]={1,2};
int b[2]=a;
这显示错误为无效的初始化程序。 但是我在玩这样的东西,发现 奇怪的例子如下。
int a[][3] = {1, 2, 3, 4, 5, 6};
int (*ptr)[3] = a;
这也是数组的声明,其地址由ptr指针保留,并且接受2维数组a的地址,但这未显示任何错误。 为什么有人可以用简单的话解释我?预先感谢。
答案 0 :(得分:7)
在第二个示例中,ptr
不是数组,而是指向数组的指针。
此指针用a
初始化,a
是一个数组,在这种情况下,衰减指向其第一个元素的指针。 int [6][3]
的类型为int [3]
,即大小为6的数组,其中每个元素都是类型为a
的数组。因此,指向int (*)[3]
元素的指针的类型为ptr
,与类型--all and --tags are incompatible
相匹配。
答案 1 :(得分:2)
您的老师是对的-数组表达式可能不是作业的目标。但是,
中发生了什么int b[2] = a;
是声明 中数组的初始化器,必须是用大括号分隔的值序列。表达式a
不是用大括号分隔的序列,因此是错误。
您的老师在谈论的是类似情况
int b[N];
...
b = some_expression;
这是不允许的-您无法使用=
运算符将其分配给 array 。
您可以分配给单个数组元素(只要这些元素本身不是数组):
b[i] = some_value;
b[j] = a[i];
除非它是sizeof
或一元&
运算符的操作数,或者是用于初始化声明中的字符数组的字符串文字,否则 expression 为类型“ T
的N元素数组将被转换(“衰减”)为类型“指向T
的指针”的表达式,该表达式的值将是的第一个元素的地址数组。
声明
int a[][3] = {1, 2, 3, 4, 5, 6};
创建由int
的3元素数组组成的2元素数组。图形化:
+---+
a: | 1 | a[0][0]
+---+
| 2 | a[0][1]
+---+
| 3 | a[0][2]
+---+
| 4 | a[1][0]
+---+
| 5 | a[1][1]
+---+
| 6 | a[1][2]
+---+
因此,当 expression a
出现在行中
int (*ptr)[3] = a;
从类型“ {{1}的3元素数组的2元素数组”转换为“ int
的3元素数组的指针”或int
的转换,表达式的值是int (*)[3]
的地址。由于您将a[0][0]
声明为指向ptr
的3元素数组的指针,因此初始化起作用,并且int
指向数组的第一个元素(ptr
):
a[0]
由于 +---+
a: | 1 | a[0][0] <--- ptr
+---+
| 2 | a[0][1]
+---+
| 3 | a[0][2]
+---+
| 4 | a[1][0]
+---+
| 5 | a[1][1]
+---+
| 6 | a[1][2]
+---+
指向ptr
的3元素数组,因此int
将指向ptr+1
的 next 3元素数组(int
)
a[1]
编辑:
一个方便的图表,用于涉及数组,函数和指针的声明:
+---+
a: | 1 | a[0][0] <--- ptr
+---+
| 2 | a[0][1]
+---+
| 3 | a[0][2]
+---+
| 4 | a[1][0] <--- ptr + 1
+---+
| 5 | a[1][1]
+---+
| 6 | a[1][2]
+---+
事情可能变得更加复杂:
T *a[N]; // a is an array of pointers to T
T (*a)[N]; // a is a pointer to an array of T
T *f(); // f is a function returning a pointer to T
T (*f)(); // f is a pointer to a function returning T