C 指针与二维数组

标签 c arrays pointers

我正在学习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. 如何访问二维数组中的元素

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

最佳答案

这些

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];

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

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 指针与二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46779422/

相关文章:

java - 删除数组java中的特殊字符[]

c - 内存对齐和结构大小

c - 在C编程linux中读写mp3二进制文件

c - 在我的 C 代码中收到 2 个错误,指出 “undefined reference”

javascript - 遍历数组并计算数组部分的平均值

ios - swift 将从@escaping 接收到的值分配给另一个类中的实例变量

c:忽略返回并重复函数

C - 指向指针的指针问题,似乎看不到

c++ - 没有匹配函数来调用 C++

c - 嵌套结构指针无法访问地址 0x8 处的内存