带2D数组的C指针

带2D数组的C指针,c,arrays,pointers,C,Arrays,Pointers,我正在学习C语言,对2D数组指针感到困惑 我有以下声明 int a[3][5]; int *b[3][3]; int (*c)[3][5]; int *(d[3][5]); int (*e[3])[5]; 谁能帮我澄清一下吗 是否有有效的声明 a、b、c、d、e的大小(假设在64位机器上,地址id为8字节) 他们指的是什么 如何访问二维数组中的元素 我对2D数组中指针的用法完全感到困惑…我猜其中一些是等效的…但有些可能不是很好的实践 int a[3][5]; int *b[3][5]; (我

我正在学习C语言,对2D数组指针感到困惑

我有以下声明

int a[3][5];
int *b[3][3];
int (*c)[3][5];
int *(d[3][5]);
int (*e[3])[5];
谁能帮我澄清一下吗

  • 是否有有效的声明
  • a、b、c、d、e的大小(假设在64位机器上,地址id为8字节)
  • 他们指的是什么
  • 如何访问二维数组中的元素
  • 我对2D数组中指针的用法完全感到困惑…我猜其中一些是等效的…但有些可能不是很好的实践

    int a[3][5];
    int *b[3][5];
    
    (我想你的意思确实是
    int*b[3][5]
    ,而不是你问题中所写的
    int*b[3][3]
    ) 二维数组的两个声明

    第一个数组的元素具有类型
    int
    。 第二个数组的元素的类型为
    int*

    要访问数组的元素,您可以使用订阅,例如

    a[i][j]
    b[i][j]
    其中
    i
    是范围
    [0,3]
    中的索引,
    j
    是范围[0,5]中的索引

    要让第二个数组访问数组元素指向的对象,可以使用类似于
    *b[i][j]

    sizeof(a)
    等于
    3*sizeof(int[5])
    这反过来又等于
    3*5*sizeof(int)

    sizeof(b)
    等于
    3*sizeof(int*[5])
    这反过来又等于
    3*5*sizeof(int*)

    这个

    是指向
    int[3][5]
    类型的二维数组的指针声明。 你可以写一个例子

    int (*c)[3][5] = &a;
    
    其中
    a
    是上面声明的二维数组

    要访问定点数组的元素,可以使用以下语法

    ( *c )[i][j]
    
    这个

    二维数组元素的声明,其类型为
    int*
    。 此声明等同于上面显示的声明,即

    int *b[3][5];
    
    您可以将声明符括在括号中,这样您甚至可以像这样编写数组
    d
    的声明

    int * (((d)[3])[5]);
    
    这个

    是一个数组的声明,其中包含指向
    int[5]
    类型数组的3个指针元素。 使用typedef

    typedef int T[5]; 
    
    数组声明可以重写为

    T * e[3];
    
    这里是一个演示程序,显示如何访问数组
    e
    的元素

    #include <stdio.h>
    
    int main( void )
    {
        int a1[5] = { 1, 2, 3, 4, 5 };
        int a2[5] = { 10, 20, 30, 40, 50 };
        int a3[5] = { 100, 200, 300, 400, 500 };
    
        int(*e[3])[5] = { &a1, &a2, &a3 };
    
        for (size_t i = 0; i < sizeof( e ) / sizeof( *e ); i++)
        {
            for (int j = 0; j < sizeof(*e[i]) / sizeof(**e[i]); j++)
            {
                printf( "%3d ", ( *e[i] )[j] );
            }
            putchar( '\n' );
        }
    
        return 0;
    }
    

    如果b是[3][5]而不是[3][3],则b和d的可能重复项将是相同的。我假设您希望它是[3][5]?2D数组是由1D数组组成的数组。例如,由
    行组成的数组是由1D数组的数量组成的。
    int*b[3][3]
    是指向type
    int
    int(*c][3][5]的指针组成的2D数组
    是指向
    int*(d[3][5])的3x5数组的指针;
    *d[3][5]和
    int(*e[3])[5]相同;
    是指向3
    int
    (其中5个)@DavidC.Rankin否:
    d
    与b相同(除了3对5)-括号无效,
    e
    是一个由3个指针组成的数组,指向5个整数的数组。特别是sizeof(e)is 3*8=24。很好,汤姆。谢谢你的详细解释!但是有什么规则可以解析指针声明吗?我不想死记硬背。对于C专家来说,这可能很明显,但对我来说很难理解。@ZiqiLiu只需将最左边的数组替换为指针。例如int(a[n1])[n2][n3];int(*p)[n2][n3]=a;此声明是否也留出了内存空间?是否为3个整数数组指针和每个指针上y个整数在内存中创建了空间?如果是,该内存将如何组织?@etienz创建了一个由三个指针组成的数组,仅此而已。
    typedef int T[5]; 
    
    T * e[3];
    
    #include <stdio.h>
    
    int main( void )
    {
        int a1[5] = { 1, 2, 3, 4, 5 };
        int a2[5] = { 10, 20, 30, 40, 50 };
        int a3[5] = { 100, 200, 300, 400, 500 };
    
        int(*e[3])[5] = { &a1, &a2, &a3 };
    
        for (size_t i = 0; i < sizeof( e ) / sizeof( *e ); i++)
        {
            for (int j = 0; j < sizeof(*e[i]) / sizeof(**e[i]); j++)
            {
                printf( "%3d ", ( *e[i] )[j] );
            }
            putchar( '\n' );
        }
    
        return 0;
    }
    
      1   2   3   4   5
     10  20  30  40  50
    100 200 300 400 500