六:指针与多维数组

这一节我们将讨论指针与多维数组的关系。开始之前,让我们回顾一下什么是多维数组。

1. 声明数组

数组是由一系列类型相同的数据对象依次排列组成的复合结构。那么声明数组时至少要提供三类参数:
1. 数组名。
2. 数组元素的类型。
3. 数组元素的数量。

数组声明的公式为:

```
类型 数组名[元素数量];
```

例如,一个数组 A,它的元素为 `int` 类型,元素数量为10个。
1. 数组名:A
2. 数组元素的类型:int
3. 数组元素的数量:10

数组 A 的声明如下:

```
int A[10];
```

假设另一个数组 B,它的元素类型为数组 `int[10]`,元素数量为5个。
1. 数组名:B
2. 数组元素的类型:int[10]
3. 数组元素的数量:5

数组 B 的声明如下:

```
int B[5][10];
```

访问数组 A 的元素需要一个下标,例如 `A[x]`。而访问数组 B 的元素需要两个下标,例如 `B[x][y]`。数组 A 为一维数组,而数组 B 为二维数组。

2. 数组名的转换规则

数组名出现在表达式中时,将被转换为指向数组首元素的指针。但有两个例外:
1. 对数组名使用 `sizeof` 时。
2. 对数组名使用 `&` 时。

3. 多维数组名与指针

通过实际示例探讨指针与多维数组的关系:

```
#include <stdio.h>
int main()
{
    int A[10];
    int B[5][10];

    printf("sizeof A = %lu\n", sizeof(A));
    printf("sizeof B = %lu\n", sizeof(B));

    return 0;
}
```

在上面的代码中,A 的类型为 `int[10]`,B 的类型为 `int[5][10]`。

A 的空间大小为 `sizeof(int) * 10 = 40`。
B 的空间大小为 `sizeof(int[10]) * 5 = 200`。

接下来探讨数组名被转换的情况:

```
#include <stdio.h>
int main()
{
    int A[10];
    int B[5][10];

    int *pA;
    int (*pB)[10];

    pA = A;
    pB = B;

    return 0;
}
```

在上面的代码中,数组名 A 将被转换为指向数组首元素的指针类型 `int *`,数组名 B 将被转换为指向数组首元素的指针类型 `int (*)[10]`。

```
#include <stdio.h>
int main()
{
    int B[5][10] = {
        {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
        {10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
        {20, 21, 22, 23, 24, 25, 26, 27, 28, 29},
        {30, 31, 32, 33, 34, 35, 36, 37, 38, 39},
        {40, 41, 42, 43, 44, 45, 46, 47, 48, 49}
    };
    int (*pInt10)[10] = B;
    printf("pInt10 = %p\n", pInt10);
    printf("pInt10 + 1 = %p\n", pInt10 + 1);
    printf("pInt10 + 2 = %p\n", pInt10 + 2);

    return 0;
}
```

在上面的代码中,指针 `pInt10` 被初始化为指向数组 B 的首元素,即类型转换为 `int (*)[10]`。我们可以通过移动指针访问不同数组:

```
#include <stdio.h>
int main()
{
    int B[5][10] = {
        {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
        {10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
        {20, 21, 22, 23, 24, 25, 26, 27, 28, 29},
        {30, 31, 32, 33, 34, 35, 36, 37, 38, 39},
        {40, 41, 42, 43, 44, 45, 46, 47, 48, 49}
    };
    int (*pInt10)[10] = B;
    int *pInt = *pInt10;

    printf("pInt[0] = %d\n", pInt[0]);
    printf("pInt[1] = %d\n", pInt[1]);
    printf("pInt[2] = %d\n", pInt[2]);

    return 0;
}
```

在这个例子中,`pInt10` 先从 `int (*)[10]` 转换为 `int [10]`,然后从 `int [10]` 转换为 `int *`。通过 `pInt10` 可以遍历整个二维数组的元素。

4. 指针与数组名互换访问

任何数组在内存中都是连续的,二维数组也不例外:

```
#include <stdio.h>
int main()
{
    int B[5][10] = {
        {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
        {10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
        {20, 21, 22, 23, 24, 25, 26, 27, 28, 29},
        {30, 31, 32, 33, 34, 35, 36, 37, 38, 39},
        {40, 41, 42, 43, 44, 45, 46, 47, 48, 49}
    };
    int *pInt = B[0];

    printf("pInt[0] = %d\n", pInt[0]);
    printf("pInt[1] = %d\n", pInt[1]);
    printf("pInt[2] = %d\n", pInt[2]);
    printf("pInt[10] = %d\n", pInt[10]);

    return 0;
}
```

5. 对数组取地址

当对数组名使用 `&`,不会进行类型转换。例如,对于 `int arr[10];`,`&arr` 的类型为 `int (*)[10]`:

```
#include <stdio.h>
int main()
{
    int arr[10];
    int (*pInt10)[10] = &arr;

    printf("pInt10 = %p\n", pInt10);
    printf("pInt10 + 1 = %p\n", pInt10 + 1);

    return 0;
}
```

通过这种方法,我们可以正确地使用指针指向数组并操作数组的数据。

通过这些示例,我们可以更加清晰地理解指针与多维数组的关系,并且可以灵活地对多维数组进行遍历和操作。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值