C++ 为什么可以';我们不能直接将2D数组的地址分配给指针吗?

C++ 为什么可以';我们不能直接将2D数组的地址分配给指针吗?,c++,c,multidimensional-array,implicit-conversion,explicit-conversion,C++,C,Multidimensional Array,Implicit Conversion,Explicit Conversion,为什么我们不能直接将2D数组的地址分配给指针 我们有没有办法不借助for循环,在一行中分配它 还有其他更好的方法吗 //指向4个整数数组的5个指针数组 int(*Aop[5])[4]; 对于(inti=0;i此声明 int (*Aop[5])[4]; 不声明指针。它是指向int[4]的一维数组的5个指针数组的声明 数组没有赋值运算符。但是您可以在其声明中初始化它,例如 int (*Aop[5])[4] = { &arr2[0], &arr2[1], &arr2[2],

为什么我们不能直接将2D数组的地址分配给指针

我们有没有办法不借助
for
循环,在一行中分配它

还有其他更好的方法吗

//指向4个整数数组的5个指针数组
int(*Aop[5])[4];
对于(inti=0;i此声明

int (*Aop[5])[4];
不声明指针。它是指向
int[4]
的一维数组的5个指针数组的声明

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

int (*Aop[5])[4] = { &arr2[0], &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;
}
如果需要声明指向数组
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;
}
本声明

int (*Aop[5])[4];
不声明指针。它是指向
int[4]
的一维数组的5个指针数组的声明

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

int (*Aop[5])[4] = { &arr2[0], &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;
}
如果需要声明指向数组
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;
}

声明指向整个数组的指针时,这些操作非常有效:

int (*Ap)[4] = arr2;

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

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

声明指向整个数组的指针时,这些操作非常有效:

int (*Ap)[4] = arr2;

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

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

数组初始值设定项必须是文本,不能相互分配数组。这里的
int(*Aop[5])[4];
是什么意思?您的意图不清楚。指向“fixed”数组的指针大小是有点无用的,因为没有边界检查。当问这样的问题时,请关注C或C++中的一个。它们的行为可以有很大的不同。如果你使用<代码> STD::vector < /代码>,你可以分配它们,这样你就不用担心原始指针和手动复制。这也是为什么你不应该标记BO。THC和C++因为如果你问C,答案明显不同于C++的数组,初始化器必须是文字,你不能给彼此分配数组。<代码> int(*AOP(5))[4 ];< /Cord>这里是什么意思?你的意图不清楚。指向“固定”数组的指针大小是有点无用的,因为没有边界检查。当问这样的问题时,请关注C或C++中的一个。它们的行为可以有很大的不同。如果你使用<代码> STD::vector < /代码>,你可以分配它们,这样你就不用担心原始指针和手动复制。这也是为什么你不应该标记BO。THC和C++因为如果你问C,答案明显不同于C++