如何将二维数组的基地址赋给指针?

3
假设我们有:
int a[2][3] ;
int (*p)[3]=a; // is ok
int (*p)[3]=&a[0]; // is also ok

但是为什么呢?
int (*p)[3]=a[0]; 

尽管a[0]给出了第一个数组的地址(因为2D数组是数组的数组),似乎比&a[0]更好,但仍然可以使用&a[0]来获得第一个数组的第一个元素的地址。这可能会产生错误,请注意。

4个回答

5
除非它是sizeof或一元&运算符的操作数,或者是用于声明中初始化另一个数组的字符串字面量,否则类型为“N个T元素数组”的表达式将被转换(“衰减”)为类型为“指向T的指针”的表达式,并且表达式的值将是数组的第一个元素的地址。
给定以下声明:
int a[2][3];

那么以下内容是正确的:

        Expression        Type            Decays To      Equivalent Value
        ----------        ----            ---------      ----------------
                 a        int [2][3]      int (*)[3]     &a[0]
                &a        int (*)[2][3]   n/a            n/a
                *a        int [3]         int *          a[0]
              a[i]        int [3]         int *          n/a
             &a[i]        int (*)[3]      n/a            n/a
             *a[i]        int             n/a            a[i][0]
           a[i][j]        int             n/a            n/a

请注意,a&a*aa[0]&a[0]以及&a[0][0]相同(数组的第一个元素的地址与整个数组的地址相同),但类型不同。
从上面的表格中可以看出,表达式a[0]的类型为“3个int元素的数组”;由于该表达式不是sizeof或一元&运算符的操作数,因此它会被转换为类型为“指向int的指针”的表达式,这种类型与“指向3个int元素的数组”的指针不兼容,这就是为什么int (*p)[3] = a[0];会出错的原因。

1
很好的解释。+1。 - haccks
但是在这种情况下,我们如何检查像*a和&a[i]这样的表达式的类型,例如2D数组? - OldSchool
请帮帮我,我已经在这个主题上花了10天的时间。 - OldSchool

2
因为a[0]不是指针类型,而是int [3]类型。它是一个由3个整数组成的块,可以被分配给这样的变量,但不能被分配给指针变量。

不是,aint[2][3] 类型。 - Lundin

2
int (*p)[3]=a; // is OK  

因为a的类型是int (*)[3](指向包含3个int元素的数组的指针),在转换为第一个元素后,也就是p的类型。赋值是合法的。

int (*p)[3]=&a[0]; // is also OK  

因为&a[0]也是类型为int (*)[3](第一行的地址)

int (*p)[3]=a[0]; // is not OK  

因为在转换为第一行的第一个元素后,a[0] 的类型为 int *。不同指针类型之间的赋值是非法的。


嘿,int(*p)[3] = a; 是可以的。 - OldSchool

0

如何让a [0]既可以是int类型,又可以是int [3]类型,因为我们已经将其声明为二维数组


a[0] 不是 int 类型。它是 int[3] 类型,即包含 3int 的数组,被转换为 int * - haccks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接