再学C语言40:指针和多维数组

函数通过指针对多维数组进行处理

int arr[3][4]; 

1)数组名arr同时也是数组首元素的地址

2)arr是数组首元素的地址,arr的值和&arr[0]相同;arr[0]本身是包含4个整数的数组,arr[0]的值同其首元素的地址&arr[0][0]相同;另个整数组成的数组开始于同一地址,arr和arr[0]具有相同的数值

3)对一个指针(即地址)加1,会对原来的数值加上一个对应类型大小的数值;arr所指向的对象的大小是2个int,arr[0]所指向的对象的大小是1个int,因此arr + 1和arr[0] + 1的结果不同

4)对一个指针(即地址)取值(使用运算符*或带索引的[]运算符)得到的是该指针所指向的对象的数值;arr[0]是其首元素arr[0][0]的地址,所以*(arr[0])代表存储在arr[0][0]中的数值,即一个int数值;*arr代表其首元素arr[0]的值,但是arr[0]本身就是一个int数的地址,即&arr[0][0],因此*arr是&arr[0][0],因此**arr等价于*&arr[0][0],即等价于arr[0][0];arr是地址的地址,需要两次取值(**arr)才可以得到通常的数值

地址的地址(或指针的指针)是双重间接的典型例子

示例代码:

#include <stdio.h>

int main(void)
{
    int arr[3][4] = {
        {1, 2,  3,  4 },
        {5, 6,  7,  8 },
        {9, 10, 11, 12}
    };

    printf("arr = %p, arr + 1 = %p\n", arr, arr + 1);
    printf("arr[0] = %p, arr[0] + 1 = %p\n", arr[0], arr[0] + 1);
    printf("*arr = %p, *arr + 1 = %p\n", *arr, *arr + 1);
    printf("arr[0][0] = %d\n", arr[0][0]);
    printf("*arr[0] = %d\n", *arr[0]);
    printf("**arr = %d\n", **arr);
    printf("arr[2][1] = %d\n", arr[2][1]);
    printf("*(*(arr + 2) + 1) = %d\n", *(*(arr + 2) + 1));
}

运行结果:

a4c2f875f80c402d9dbf3200b3d9ec47.png

一、如何声明指向二维数组的指针变量

int main(void)
{
    int arr[3][4] = {
        {1, 2,  3,  4 },
        {5, 6,  7,  8 },
        {9, 10, 11, 12}
    };
    int (* p) [4]; // p是指向包含4个int值的数组的指针
    p = arr;
    ...
}

尽管p是一个指针,不是数组名,依然可以使用p[2][1]这样的符号

二、指针的兼容性

指针之间的赋值规则比数值类型的赋值更加严格

例如,对于数值类型,可以不需要进行类型转换就直接把一个int数值赋给一个double类型的变量,但对于指针来说这种赋值是不被允许的

三、函数和多维数组

如果要编写处理二维数组的函数,需要很好地理解指针以便正确声明函数的类型

在函数体内,通常可以用数组符号来避免使用指针

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Forster-C

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值