具有分配地址的数组声明

时间:2018-07-10 19:42:13

标签: c arrays pointers

正如我的老师告诉我的那样,数组声明不能接受地址作为赋值。

int a[]={1,2};
int b[2]=a;

这显示错误为无效的初始化程序。 但是我在玩这样的东西,发现  奇怪的例子如下。

int a[][3] = {1, 2, 3, 4, 5, 6};
int (*ptr)[3] = a;

这也是数组的声明,其地址由ptr指针保留,并且接受2维数组a的地址,但这未显示任何错误。 为什么有人可以用简单的话解释我?预先感谢。

2 个答案:

答案 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