【问题标题】:Why can't we directly assign the address of a 2D array to a pointer?为什么我们不能直接将二维数组的地址分配给指针?
【发布时间】:2021-06-02 07:24:20
【问题描述】:

为什么不能直接将二维数组的地址赋值给指针?

有什么方法可以在一行中分配它,而不是借助 for 循环?

还有其他更好的方法吗?

// Array of 5 pointers to an array of 4 ints 

int (*Aop[5])[4];

for(int i = 0;i<5;i++) 
{
    Aop[i] = &arr2[i];  //Works fine
} 
 
//Why this doesn't work int 
int (*Aop[5])[4] = &arr2[5][4]

【问题讨论】:

  • 数组初始值设定项必须是字面量,不能相互分配数组。
  • int (*Aop[5])[4]; 在这里是什么意思?你的意图不明确。指向“固定”大小的数组的指针有点没用,因为无论如何都没有边界检查。
  • 在提出此类问题时,请关注 C 或 C++ 之一。他们的行为可能会有很大差异。
  • 如果您使用了std::vector,您可以只分配它们,您就不必担心原始指针和手动复制。这也是为什么您不应该标记 both C 和 C++ 的原因,因为如果您询问 C,答案显然与 C++ 不同

标签: c++ c multidimensional-array implicit-conversion explicit-conversion


【解决方案1】:

此声明

int (*Aop[5])[4];

不声明指针。它是一个由 5 个指针组成的数组的声明,指向 int[4] 的一维数组。

数组没有赋值运算符。但是,您可以在其声明中对其进行初始化,例如

int (*Aop[5])[4] = { &arr2[0], &arr2[1], &arr2[2], &arr2[3], &arr2[4] };

int (*Aop[5])[4] = { arr2, arr2 + 1, arr2 + 2, arr2 + 3, arr2 + 4 };

这是一个演示程序。

#include <stdio.h>

int main(void) 
{
    enum { M = 5, N = 4 };
    
    int arr2[M][N] =
    {
        { 1, 1, 1, 1 },
        { 2, 2, 2, 2 },
        { 3, 3, 3, 3 },
        { 4, 4, 4, 4 },
        { 5, 5, 5, 5 }
    };
    
    int (*Aop[M])[N] = { arr2, arr2 + 1, arr2 + 2, arr2 + 3, arr2 + 4 };
    
    for ( size_t i = 0; i < M; i++ )
    {
        for ( size_t j = 0; j < N; j++ )
        {
            printf( "%d ", ( *Aop[i] )[j] );
        }
        putchar( '\n' );
    }
    
    return 0;
}

程序输出是

1 1 1 1 
2 2 2 2 
3 3 3 3 
4 4 4 4 
5 5 5 5

如果您需要声明指向数组arr2 的指针,那么您应该记住,数组指示符被隐式转换(极少数例外)为指向其第一个元素的指针。数组arr2 具有int[4] 类型的元素。因此,指向该类型对象的指针将具有int ( * )[4] 类型。所以你可以写

int (*Aop )[4] = arr2;

这是另一个演示程序,它使用 for 循环中的指针来输出数组 arr2 的元素。

#include <stdio.h>

int main(void) 
{
    enum { M = 5, N = 4 };
    
    int arr2[M][N] =
    {
        { 1, 1, 1, 1 },
        { 2, 2, 2, 2 },
        { 3, 3, 3, 3 },
        { 4, 4, 4, 4 },
        { 5, 5, 5, 5 }
    };
    
    int (*Aop )[N] = arr2;
    
    for ( int ( *p )[N] = Aop; p != Aop + M; ++p )
    {
        for ( int *q = *p; q != *p + N; ++q )
        {
            printf( "%d ", *q );
        }
        putchar( '\n' );
    }
    
    return 0;
}

程序输出又是

1 1 1 1 
2 2 2 2 
3 3 3 3 
4 4 4 4 
5 5 5 5

【讨论】:

    【解决方案2】:

    这些可以很好地声明指向整个数组的指针:

    int (*Ap)[4] = arr2;
    
    int (*Bp)[5][4] = &arr2;
    

    数组的大小只出现在它的声明中,而不是在传递它时。 arrs[5][4] 是一个越界数组访问(超出了整行和整列的范围,因此您甚至不能通过避免左值到右值的转换来合法地将其用作过去的引用)

    【讨论】:

      猜你喜欢
      • 2020-07-02
      • 2021-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-17
      • 1970-01-01
      • 2011-05-27
      相关资源
      最近更新 更多