第8章 再论指针
单个元素的存储和引用实际上是以线性形式排列在内存中的。
可以通过声明一个一维指针数组,其中每个指针指向一个字符串来取得类似二维字符数组的效果。用于实现多维数组的指针数组可称为Iliffe向量。
只要有可能,尽量不要选择拷贝整个字符串的方法。拷贝一个指针比拷贝整个数组快得多,空间也节省很多。
数组和指针参数是如何被编译器修改的:
实参 所匹配的形式参数
数组的数组 数组指针
指针数组 指针的指针
数组指针 不改变
指针的指针 不改变
在C语言中,任何一维数组均可以作为函数的实参。形参被改写为指向数组第一个元素的指针,所以需要一个约定来提示数组的长度。一般有两个基本方法:
1、增加一个额外的参数,表示元素的数目。
2、赋予数组最后一个元素一个特殊的值,提示它是数组的尾部。
二维数组的情况要复杂一些,数组被改写为指向数组第一行的指针。现在需要两个约定,其中一个用于提示每行的结束,另一个用于提示所有行的结束。
C编译器必须要知道数组的边界,以便为下标引用产生正确的代码。从技术上说,也可以在运行时处理才知道数组的边界,但这种做法违背了C语言的设计理念。
如果多维数组各维的长度都是一个完全相同的固定值,那么把它传递给一个函数毫无问题。如果情况更普通一些,也更常见一些,就是作为函数的参数的数组的长度是任意的,我们用下面的方法进行进一步的分析:
1、一维数组—没有问题,但需要包括一个计数值或者是一个能够标识越界位置的结束符。被调用函数无法检测数组参数的边界。
2、二维数组—不能直接传递给函数,但可以吧矩阵改写为一个一维的Iliffe向量,并使用相同的下标标识方法。对于字符串来说,这样做是可以的,对于其它类型,需要增加一个计数值或者能够标识越界位置的结束符。
3、三维或更多维的数组—都无法使用。必须把它分解为几个维数更少的数组。
无法直接从函数返回一个数组,但是可以让函数返回一个指向任何数据结构的指针,当然也可以是一个指向数组的指针。
当预先并不知道数组长度时,可以使用动态数组。然而在ANSI C中数组是静态的—数组的长度在编译时便已确定不变。
C语言中实现动态数组的基本思路就是使用malloc()库函数(内存分配)来得到一个指向一大块内存的指针。然后,像引用数组一样引用这块内存,其机理就是一个数组下标访问可以改写为一个指针加上偏移量。可以使用库函数relloc()对内存块大小进行重新分配,同时不会丢失原先内存块的内容。
文章评论(0条评论)
登录后参与讨论