【问题标题】:C pointer with 2D array带有二维数组的 C 指针
【发布时间】:2017-10-16 21:31:40
【问题描述】:

我正在学习 C 语言,但我对二维数组指针感到困惑。

我有以下声明

int a[3][5];
int *b[3][3];
int (*c)[3][5];
int *(d[3][5]);
int (*e[3])[5];

谁能帮我解释一下

  1. 是否有有效的声明
  2. a,b,c,d,e 的大小(假设在 64 位机器上,地址 id 为 8 个字节)
  3. 他们指向什么
  4. 如何访问二维数组中的元素

我对二维数组中指针的使用完全感到困惑......我猜其中一些是等价的......但有些可能不是好习惯

【问题讨论】:

  • 如果 b 是 [3][5] 而不是 [3][3],b 和 d 将是相同的。我假设您打算将其设为 [3][5]?
  • 二维数组是一维数组的数组。例如,rows 一维数组数量的数组。 int *b[3][3] 是指向int 类型的指针的二维数组。 int (*c)[3][5] 是一个 指向int 的 3x5 数组的指针 int *(d[3][5]);*d[3][5] 相同,int (*e[3])[5]; 是一个指向 3 个 int(其中 5 个)
  • @DavidC.Rankin 否:d 与 b 相同(除了 3 和 5)- 括号无效,e 是 3 个指针的数组,其中指向 5 个整数的数组。特别是 sizeof(e) 是 3*8 = 24。
  • 不错的汤姆。

标签: c arrays pointers


【解决方案1】:

这些

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 (*c)[3][5];

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

int (*c)[3][5] = &a;

其中a 是上面声明的二维数组。

要访问指向数组的元素,您可以使用此语法

( *c )[i][j]

这个

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

一个二维数组元素的声明,其类型为int *。 这个声明等价于上面显示的声明就是

int *b[3][5];

您可以将声明符括在括号中。所以你甚至可以写数组的声明d 就像

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

这个

int (*e[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;
}

程序输出是

  1   2   3   4   5
 10  20  30  40  50
100 200 300 400 500

【讨论】:

  • 感谢非常详细的解释!但是有什么规则可以解析指针声明吗?我不想死记硬背。也许对于 C 专家来说这很明显,但对我来说很难理解。
  • @ZiqiLiu 只需将最左边的数组替换为指针即可。例如 int ( a[n1] )[n2][n3]; int ( *p )[n2][n3] = a;
  • 这个声明是否也预留了内存空间?它是否在内存中为 3 个 int 数组指针和每个指针的 y 个整数创建空间?如果是这样,这段记忆将如何组织?
  • @etienz 创建了一个由三个指针组成的数组,仅此而已。
猜你喜欢
  • 1970-01-01
  • 2019-04-11
  • 2016-06-23
  • 2017-04-26
  • 1970-01-01
  • 2013-09-30
  • 2017-06-11
  • 1970-01-01
  • 2016-05-08
相关资源
最近更新 更多