lliffe向量
可以通过声明一个一维指针数组,其中每个指针指向一个字符串来取得类似二维字符数组的效果。这种方法的声明是:char *pea[4]; (你能用第三章的读声明的方法明白这个声明什么意思吗?)
这是c语言中最常见最重要的数据结构。被称作lliffe向量。这种锯齿形的数组用于储存字符串。
这种数组必须用指向为字符串而分配的内存的指针进行初始化。可以在编译时用一个常量初始值,以可以在运行时动态分配。动态分配有两种方法。(图)
当你看到squash[i][j]这样的形式时,squash有可能是
int squash[23][12];
int * squash[23];
int **squash;
int (*squash)[12]。
数组和指针参数是如何被编译器编译的
向函数传递数组的方法:
向函数传递一个一维数组:任何一维数组都可以作为函数的参数。但是形参被改写成指向数组第一个元素的指针,因此需要一个约定来提示数组的长度。一般有三种方法:
- 1增加一个额外的参数,表示元素的数目。
- 2赋予数组最后一个元素一个特殊的值。
- 3让数组第0个元素记录元素的个数。(这种方法是笔者见过的方法,书上没有介绍)。
向函数传递一个多维数组:有四种方法。
1直接传递数组。void func(int pea[10][20]),这种方法局限性很大。因为你无法传入peach[10][9]这样的数组了。
2省略第一维的长度。void func(int pea[][20])或void func(int (*pea)[20]);但这与第一种方法有类似的局限性。
3使用lliffe向量。void func(int **pea); 注意只有把二维数组改写成指向向量的指针数组才行。主要用于字符串数组。因为它们有明确的结尾。另外还需要一个计数的量,比如main函数的argc。
4放弃多维数组的形式,提供自己的下标方式。传入一个普通指针。然后在内部采用这种方式访问数组:char_array[i*row_size+j]。这时需要传入row_size和column_size。采用这种方法,数组的长和宽必须是固定的。
总之,如果长宽都固定,上面的方法都可以有用。
但,如果长宽都不固定,一维数组可以用过上述方法解决。二维数组中字符串数组可以采用lliffe向量方式解决。其他数组需要设定结尾值,但很难做到统一完美。而对于三维及以上数组,无法传递,只能进行拆分成一维数组等。
对多维数组作为参数传递的支持缺乏是c语言的一个缺陷。
更多注意:
使用指针从函数返回一个数组:不能返回局部变量。(第二章已经讲了五种方法)
使用指针创建和使用动态数组:
使用malloc和realloc。注意不要把realloc的返回值直接赋给字符指针。因为如果该函数失败,它会使该指针的值变为NULL,这样原有数据就出错了。