C--《C和指针》第8章读书笔记之多维数组

我认为这本书将多维数组的概念讲的非常透彻,而且浅显易懂,经典书籍果然名不虚传~~


1、多维数组及指向数组的指针的引出

    一维数组名的值是一个指针常量,它的类型是“指向元素类型的指针”,它指向数组的第一个元素。多维数组的第1维的元素实际上是另一个数组。

如: int ppp[3][10];

    创建ppp,它可以看做是一个一维数组,包含3个元素,只是每个元素恰好是包含10个整形元素的数组。

ppp这个名字的值是一个指向它第1个元素的指针,所以ppp是一个指向一个包含10个整形元素的数组的指针。

2、多维数组的下标是如何工作的?

    数组的下标引用实际上只是间接访问的一种伪装形式,在多维数组中也是如此。

考虑如下表达式: int ppp[3][10];

ppp的类型是“指向包含10个整形元素的数组的指针”,它指向包含10个整形元素的第1个子数组。


表达式Ppp+1指向ppp的另一行:

那表达式*(ppp+1)呢?ppp+1标识了1个子数组,*(ppp+1)则指向子数组的第一个元素。


那表达式*(ppp+1)+5呢?*(ppp+1)是指向整形的指针,所以这个5根据整形的长度进行调整。表达式的结果还是一个指针,它指向的位置比上一个表达式所指向的位置向后移动了5个整形元素。


表达式*(ppp+1)+5中,*(ppp+1)可以改写为ppp[1],代入表达式可得到*(ppp[1]+5)。这个表达式是合法的,ppp[1]选定一个子数组,所以它的类型是一个指向整形的指针。对这个指针加上5,然后执行间接访问操作。这个表达式还能写成ppp[1][5]。


3、指向数组的指针

    看一下这个声明: int max[3][10],  * p = max;

这里p的初始化不正确。因为max并不是一个指向整形的指针,而是一个指向整形数组的指针。应该这样声明:int(*p)[10];

         这个声明看起来很复杂。因为括号的存在,首先执行的是间接访问。所以p是指针,那它指向什么呢?接下来执行下标引用,所以p指向某个类型的数组。声明并没有直接告诉我们p是什么,但是当我们对它执行间接访问操作时,我们得到的是个数组。对该数组进行下标引用操作得到一个整型值。所以,p是一个指向整形数组的指针。

所以应该这样声明:int  (*p)[10] = max;

它使p指向max的第1行。

 

如果想创建一个简单的整形指针,指向max的第1个整形元素,应该这样声明

Int * pi = &max[0][0] ;    或者 int * pi =max[0]; 

应该避免这样声明:int (*p)[ ] = max;

这里p仍然是一个指向整形数组的指针,但是数组的长度不见了。当某个整数与这种类型的指针执行指针运算时,有可能出错

 

4、多维数组做函数参数

         多维数组的每个元素本身是另外一个数组,编译器需要知道它的维数,以便为函数形参的下标表达式求值。

一维数组的例子:

 int vector[10];

 func1(vector);

这里func1的原型可以是下面两种中的任何一个

Void func1(int * vec);  或者void func1(intvec[ ])

作用于vec上面的指针运算把整形的长度作为它的调整因子

 

二维数组的例子:

int max[3][10];

func2(max);

这里参数max的类型是指向包含10个整形元素的数组的指针。func2的原型应该是下面两种中的一种:  

void func2(int (*mat)[10] );

void func2(int mat[ ][10]);

这里的关键在于编译器必须知道第2个及以后各维的长度才能对下标进行求值,因此在原型中必须声明这些维的长度。第1维的长度并不需要,因为在计算下标值时用不到它。

func2的原型不能写成这样:void func2(int** mat);

这样把mat声明为一个指向整形指针的指针,它和指向整形数组的指针不是一回事。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值